Im new to mobile development, especially using Ionic. Please help me out
I have this code for my route
.state('auth', {
url: '/auth',
templateUrl: 'templates/login.html',
controller: 'AuthCtrl'
I have this code for my login.html
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<div class="list list-inset">
<label class="item item-input">
<input type="text" placeholder="Mobile Number" ng-model="mobile_number">
</label>
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
and for my AuthCtrl
.controller('AuthCtrl', function($scope,$auth,$state) {
$scope.login = function() {
var credentials = {
mobile_number : $scope.mobile_number,
password : $scope.password,
}
console.log(credentials);
$auth.login(credentials).then(function(data) {
// If login is successful, redirect to the users state
$state.go('tab.dash', {});
});
}
})
I always get this Object {mobile_number: undefined, password: undefined} when calling console.log(credentials)
I always put values in my forms, but its always undefined. Why?
First initialize your scope credentials model:
$scope.credentials = {
'mobile_number' : ''
'password' : '',
}
Then bind your inputs to the scope properties:
<input type="text" placeholder="Mobile Number" ng-model="credentials.mobile_number">
<input type="password" placeholder="Password" ng-model="credentials.password">
And make use of $scope.credentials that now has your form data:
$auth.login($scope.credentials).then(function(data) {
// If login is successful, redirect to the users state
$state.go('tab.dash', {});
});
Your credentials object is not bound to scope. It looks like You need to declare $scope.credentials outside of login. Also on the input, ngModel should bind to credentials.password and credentials.mobile_number.
Actually it works good for me, I did a little plunker to test it. I was facing similar problem cause I added ng-pattern and ng-minLength directive in the input. In this case you will get undefined unless the input value is valid pattern and length. To fix it I added property to your input element
<input type="tel" ng-model="credentials.mobile_number"
ng-model-options="{allowInvalid:true}"/>
I hope that helps , good luck
Related
I'm creating a form with Angular and Angular Messages. This form lies in a template that gets brought into the view with Angular Route. When I first load the form, everything functions properly. Then, when I load a different view and switch back to the form's view, I'm unable to focus on the text inputs. What's happening?
The HTML
<form name='submission' ng-submit='submit()'>
<label class='text-input-group' for='name'>
<div class='label'>Name</div>
<input id='name' name='name' ng-model='submissionName' type='text' required>
<div ng-messages='submission.name.$error' ng-if='submission.name.$touched'>
<div ng-message='required'>* Please enter your name</div>
</div>
</label>
<label class='text-input-group' for='email'>
<div class='label'>Email</div>
<input id='email' name='email' ng-model='submissionEmail' type='email' required>
<div ng-messages='submission.email.$error' ng-if='submission.email.$touched'>
<div ng-message='required'>* Please enter your email address</div>
<div ng-message='email'>* Please enter a valid email address</div>
</div>
</label>
<label class='text-input-group' for='message'>
<div class='label'>Message</div>
<textarea id='message' name='message' ng-model='submissionMessage' ng-maxlength='2000' maxlength='2000' required></textarea>
<div ng-messages='submission.message.$error' ng-if='submission.message.$touched'>
<div ng-message='required'>* No message?</div>
<div ng-message='maxlength'>* Your message unfortunately can't exceed 20,000 characters</div>
</div>
</label>
<label class='checkbox-input-group' for='send-user-a-copy'>
<div class='label'>Send me a copy</div>
<input id='send-user-a-copy' name='sendUserACopy' ng-init='submissionSendUserACopy = false;' ng-model='submissionSendUserACopy' type='checkbox'>
</label>
<button type='submit'>Button</button>
</form>
The JavaScript
var contact = angular.module('app.contact', ['ngRoute']);
contact.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/contact', {
templateUrl: 'partials/contact.html',
controller: 'ContactController'
});
}]);
contact.controller('ContactController', ['$scope', function($scope) {
$scope.reset = function() {
$scope.submissionName = '';
$scope.submissionEmail = '';
$scope.submissionMessage = '';
$scope.submissionSendUserACopy = '';
$scope.submission.$setPristine();
}
$scope.$on('$routeChangeSuccess', function() {
console.log($scope.submission);
$scope.reset();
});
$scope.submit = function() {
if($scope.submission.$valid) {
console.log({
'name' : $scope.submissionName,
'email' : $scope.submissionEmail,
'message' : $scope.submissionMessage,
'sendUserACopy' : $scope.submissionSendUserACopy
});
}
}
}]);
Any answers / suggestions would be greatly appreciated. Thank you!
I wrote this to solve the issue with focus not applying on route changes in Angular.
import { Directive, ElementRef, AfterContentInit } from '#angular/core';
#Directive({
selector: '[focusOnInit]'
})
export class FocusDirective implements AfterContentInit {
constructor(public el: ElementRef) {}
ngAfterContentInit() {
this.el.nativeElement.focus();
}
}
usage
<input type="text" focusOnInit>
There is an attribute autofocus introduced in HTML5. I would suggest you adding that attribute in the first input element.
<input type="text" ng-model="firstName" autofocus />
But that has a limitation too!! Currently, browsers only focus on the input element directive on page load. So you will fall into the same problem that you are currently facing. So you can simply add an Angular directive with the same name i.e. autofocus which will programmatically focus the element as that directive is executed when the same view is loaded again.
myApp.directive('autofocus', [function() {
return {
restrict: 'A',
link: function(scope, element) {
element[0].focus();
}
};
}]);
(This is the format in Angular 1, please write it in Angular 2 if you are using Angular 2.)
Since even the same view has been loaded before, Angular will execute all the directives when the view is loaded again, this directive will focus the element after you switch back from another view.
The full source code.
I don't understand why $scope not working in my LoginGuideCtrl controller. I try click on login button and should show a <p> with new data but the $scope is not updating...
Don´t forget I'm trying to achieve a modular design.
I have the following code:
guides.js
var guides = angular.module('main.guides', ['ui.router']).config(function ($stateProvider) {
$stateProvider.
state('guides.login', {
url: '/login',
templateUrl: 'modules/guides/views/login.html',
controller: 'LoginGuideCtrl'
}).
...
state('guides.mobile', {
url: '/web',
template: '<div>guildes mobile</div>',
controller: 'ListCtrl'
});
});
controller.js
var guides = angular.module('main.guides');
guides.controller('IndexCtrl', function() {
console.log('Index');
})
.controller('LoginGuideCtrl', function($scope) {
console.log('feck');
$scope.checkLogin = function(){
$scope.message = "Welcome "+$scope.name+"!"
};
})
.controller('ListCtrl', function() {
console.log('List');
})
login.html
<div class="form-group col-sm-2">
<label for="usr">Name:</label>
<input type="text" class="form-control" id="usr" ng-model="name">
</div>
<div class="form-group col-sm-2">
<label for="pwd">Password:</label>
<input type="password" class="form-control" id="pwd" ng-model="password">
</div>
<button type="button" class="btn btn-default" ng-click="checkLogin()">Login</button>
<p ng-model="message"></p>
ng-model is used with <input> tags to capture user input, by two way binding with your model value.
Since a <p> tag does not collect user input, it won't work with ng-model. Instead just do a one way binding with the value using the curly brackets:
<p>{{message}}</p>
I wrote a basic login form in this plunk http://plnkr.co/edit/xQEN1ZNN5ZEw1CSwNw97?p=preview (click on the red Log into Dashboard button on the Home route).
However for some reason I cannot get the login() method to fire in my loginCtrl controller code.
Why is this example working, and mine is not ? http://plnkr.co/edit/H4SVl6?p=preview
Instead what it's doing is an old-school URL redirect with the user/password parameters passed in as form variables. I can't figure out what's wrong.
Here is LoginCtrl code as well as the login-form.html template :
(function () {
'use strict';
angular.module('routerApp').controller('LoginCtrl',
['$rootScope', '$scope', authenticate]);
function authenticate($rootScope, $scope, userService) {
var login = this;
login.loginUser = function () {
login.dataLoading = true;
//loginService.authUser(login.user, login.password); // TO DO !!!
};
login.test = function () {
var test = true;
};
}
})();
<div ng-show="error" class="alert alert-danger">{{error}}</div>
<form ng-submit="login.loginUser()" name="form">
<div class="form-group">
<label for="username">Username</label>
<i class="fa fa-key"></i>
<input type="text" name="username" id="username" class="form-control" ng-model="login.username" required />
<span ng-show="form.username.$dirty && form.username.$error.required" class="help-block">Username is required</span>
</div>
<div class="form-group">
<label for="password">Password</label>
<i class="fa fa-lock"></i>
<input type="password" name="password" id="password" class="form-control" ng-model="login.password" required />
<span ng-show="form.password.$dirty && form.password.$error.required" class="help-block">Password is required</span>
</div>
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid || dataLoading" class="btn btn-danger">Login</button>
<img ng-if="login.dataLoading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA=="/>
</div>
</form>
In my local app, it is posting the old-style form variables via the URL, and I cannot get it to fire the login.loginUser function below inside LoginCtrl.
thnk you in advance...
Bob
for some odd reason (perhaps ui-router versioning) the controllerAs is not working.
Diana´s answer is valid, but it doesn´t use the controlleras syntax.
If you still want to use it, change the ui-router setting to:
.state('login', {
url: "/login",
templateUrl: "login-form.html",
controller: 'LoginCtrl as login',
})
That should do the trick ;)
Check it out:
http://plnkr.co/edit/OCqNexVeFFxt4kUuEVc1?p=preview
The controller change I applied is:
angular.module('routerApp').controller('LoginCtrl', function ($rootScope, $scope) {
$scope.loginUser = function () {
$scope.dataLoading = true;
//loginService.authUser(login.user, login.password); // TO DO !!!
};
$scope.test = function () {
var test = true;
};
})
and in the template I removed login. from the ng-if and ng-submit.
Here is a working plunks.
I would like to call the login function when I click the login button but keep getting the error message in the title. Can someone point out the error in my script?
login.js code below:
/*global Firebase, angular, console*/
'use strict';
// Create a new app with the AngularFire module
var app = angular.module("runsheetApp");
app.controller("AuthCtrl", function ($scope, $firebaseAuth) {
var ref = new Firebase("https://xxxxx.firebaseio.com");
function login() {
ref.authWithPassword({
email : "xxxxx",
password : "xxxx"
}, function (error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
And the code for login.html is also below:
<div class="container" style="max-width: 300px">
<form class="form-signin">
<h2 class="form-signin-heading" style="text-align: center">Please Sign In</h2>
<input type="text" class="form-control" name="username" ng-model = "username" placeholder="Email Address" required="" autofocus="" />
</br>
<input type="password" class="form-control" name="password" ng-model = "password" placeholder="Password" required=""/>
</br>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-click="login()">Login</button>
</form>
</div>
Edge case here, but I want to mention it for posterities' sake. I got this same error when using the controllerAs pattern with a form name with the same value as ng-submit. For example:
<form name="authCtrl.signUp" ng-submit="authCtrl.signUp()">
Throws: TypeError: v2.signUp is not a function
The solution was to change the name of the form to something different:
<form name="authCtrl.signUpForm" ng-submit="authCtrl.signUp()">
In my case, I was having an exact same issue as yours. However, coming across gkalpak's answer to such a scenario helped me out.
Turned out to be what I was calling was addBuddy() function, from a form named "addBuddy". The solution was to change the name of either of the two things to make one stand out or differentiable from the other. I changed the name of the form to "addBuddyForm" and voila! My function worked!
Here's a snippet of my case:
<form name="addBuddy" class="form-horizontal" novalidate>
...
<button class="btn btn-sm btn-info" ng-click="addBuddy()>Submit</button>
Which, I changed to:
<form name="addBuddyForm" class="form-horizontal" novalidate>
...
<button class="btn btn-sm btn-info" ng-click="addBuddy()>Submit</button>
...and it worked! :)
In AngularJS call the function from view it must be in the $scope.
JS
// exposes login function in scope
$scope.login = login;
HTML
<div class="container" ng-controller="AuthCtrl" style="max-width: 300px"> <!-- I notice here for include ng-controller to your main div -->
<form class="form-signin">
<h2 class="form-signin-heading" style="text-align: center">Please Sign In</h2>
<input type="text" class="form-control" name="username" ng-model = "username" placeholder="Email Address" required="" autofocus="" />
</br>
<input type="password" class="form-control" name="password" ng-model = "password" placeholder="Password" required=""/>
</br>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-click="login()">Login</button>
</form>
This may not be specific to your problem, but I was also getting this error and it took a bit to figure out why.
I had named both a function and a variable the same, with the variable assigned in the function, and so the assignment of the variable was overriding the function and it was exploding on a second run.
You'll notice in the example the uploadFile() function as an upload.uploadFile = true; This was a wonderful file that was meant to be upload.uploadingFile - a flag used to control the behavior of a spinner. Once that was fixed, the issue went away.
Example:
(function()
{
'use strict';
angular.module('aumApp.file-upload')
.controller('FileUploadCtrl', FileUploadCtrl);
function FileUploadCtrl($scope, $http)
{
upload.uploadFile = function()
{
upload.uploadFile = true;
var backendUrl = '/ua_aumcore/events/api/v1/events/uploadFile';
var fd = new FormData();
fd.append('file', upload.src);
$http({ url: backendUrl, data: fd, method: 'POST', transformRequest : angular.identity, headers: { 'Content-Type' : undefined } })
.then(function uploadSuccess(response)
{
upload.data = response.data;
upload.message = "Uploaded Succesfully.";
upload.uploadSuccess = true;
upload.uploadingFile = false;
},
function uploadFailure(response)
{
upload.message = "Upload Failed.";
upload.uploadSuccess = false;
upload.uploadingFile = false;
});
};
}
FileUploadCtrl.$inject = ['$scope', '$http'];
})();
To be callable from the view, a function must be in the $scope. Add
$scope.login = login;
to the JS code of the controller.
You also need to actually use that controller. Change
<div class="container" style="max-width: 300px">
to
<div ng-controller="AuthCtrl" class="container" style="max-width: 300px">
This is all fundamental stuff. My advice would be to learn from an AngularJS tutorial before going further.
Two enable two-way binding you have to assign your login function to $scope. Replace your code for function with this:
$scope.login=function() {
ref.authWithPassword({
email : "nick.koulias#gmail.com",
password : "Jaeger01"
}, function (error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
}
It may be a late answer by me.
But It working for me
Check form name you set
e.g. ng-form="login"
and function name
e.g. ng-click="login()"
Then it will not work . You have to change one of them.
e.g. ng-form="loginForm"
Explanation:
AngularJS 1.x registers any form DOM element that has a name property in $scope via formDirectiveFactory. This directive automatically instantiates form.FormController if the above is true:
If the name attribute is specified, the form controller is published onto the current scope under
from: angular.js:24855
Hence if you have a <form name=myForm> it will override your $scope.myForm = function() { ... }
So I have a client controller like so (with only relevant code):
angular.module('employees').controller('EmployeesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Employees',
function($scope, $stateParams, $location, Authentication, Employees) {
$scope.authentication = Authentication;
// Create new Employee
$scope.create = function() {
// Create new Employee object
var employee = new Employees ({
name: this.name,
eid: this.eid,
availibility: [monday: this.monday, tuesday: this.tuesday]
});
With a client view (again, only code relevant to the availability array)
<div class="form-group form-inline">
<label class="control-label" for="monday">Monday</label>
<label class="control-label" for="start">Start</label>
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input type="checkbox" id="monday" class="form-control" required>
<input type="time" id="start" class="form-control" required> <input type="time" id="finish" class="form-control" required>
</div>
</div>
<div class="form-group form-inline">
<label class="control-label" for="tuesday">Tuesday</label>
<label class="control-label" for="start">Start</label>
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input type="checkbox" id="tuesday" class="form-control" required>
<input type="time" id="start" class="form-control" required>
<input type="time" id="finish" class="form-control" required>
</div>
</div>
And a server controller like so:
exports.create = function(req, res) {
var employee = new Employee(req.body);
employee.user = req.user;
console.log(req.body);
employee.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(employee);
}
});
};
How can I make it so that the user can update an "availability" schedule? For some reason, when I POST the form, all I am getting is the eid and name (in the req.body). What am I doing wrong here? Can anyone point me in the direction of a resource that I could use?
Also, another question that kinda has something to do with this: Can I use ngTable to style these forms? As in, can I put forms inside of a table?
Thanks everybody for the help!
P.S. I realize the code is pretty dirty (particular the HTML code + the fact that none of my controllers are actually trying to pull data from the forms yet). Again, I don't have any real reason to continue on to that part until I know why when I POST the form, the data is not included in the post.
Things to try:
Verify spelling of availability you have availibility in your create function and it could be an issue with your setup.
It looks like you are probably using a mean.js-like setup. I would first confirm that you have added the availability field to your Employee object. In this case you would have to make the file app/model/employee.server.model.js (or where ever your model definition is to have the array)
_
new Employee({
name: {type: String},
eid: {type: String},
availibility: {type: Array,
default: []
}
}
Finally your create function looks a little funky to me. I would use a more standard definition for the array
// Create new Employee
$scope.create = function() {
// Create new Employee object
var employee = new Employees ({
name: this.name,
eid: this.eid,
availibility: [this.monday, this.tuesday]
});