I use Angular js and firebase.
For my login form and my register form, i have a controller "userController" who call function in userProvider, my service.
I want to show the firebase error message in my view. How my provider can send message to my controller ?
My code :
userController.js :
$scope.login = function(user){
userProvider.login(user);
}
userProvider.js :
this.login = function(user){
Auth.$authWithPassword({//on connecte l'utilisateur
email: user.email,
password: user.password
}).then(function(authData) {
console.log("Utilisateur connecté:", authData.uid);
$location.path('#/profil');
}).catch(function(error) {
console.error("Echec connexion:", error);
// I want return the error.code for use it in my controller
});
}
login.html :
<form ng-hide="authData" class="form-signin col-md-6" name="loginForm" novalidate >
<h2 class="form-signin-heading">Connexion</h2>
<p style="color:red;" ng-show="userDataError">{{userDataErrorMessage}}</p>
<div class="form-group" ng-class="{ 'has-error' : loginForm.email.$invalid }">
<label for="inputEmail">Email</label>
<input type="email" class="form-control" placeholder="Email address" ng-model="user.email" name="email" ng-required autofocus>
<p class="help-block text-error" ng-show="loginForm.email.$invalid">Cet email n'est pas valide</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : loginForm.password.$invalid }">
<label for="inputPassword">Password</label>
<input type="password" class="form-control" placeholder="Password" ng-model="user.password" ng-minlength="8" name="password" ng-required>
<p class="help-block text-warning" ng-show="loginForm.password.$error.minlength" >Minimum 8 caractères</p>
</div>
<button class="btn btn-lg btn-primary btn-block" ng-disabled="loginForm.$invalid" ng-click="login(user)">Connexion</button>
To chain from the function, return the derived promise.
this.login = function(user){
//return promise
return derivedPromise = (
Auth.$authWithPassword({//on connecte l'utilisateur
email: user.email,
password: user.password
}).then(function(authData) {
console.log("Utilisateur connecté:", authData.uid);
$location.path('#/profil');
}).catch(function(error) {
console.error("Echec connexion:", error);
//throw error to chain
throw error;
});
);
});
In the controller, use the promise to display the error.
$scope.login = function(user){
userProvider.login(user)
.catch( function onRejected(error) {
$scope.errorMessage = ("Echec connexion:" + error);
});
};
By returning the promise, results (either fulfilled or rejected) can be retrieved by using the .then or .catch methods of the promise.
First of all for these kinds of plans i would defintely not use a provider but a service... So what you can do to achieve your problem about showing the error to the controller is:
In loginService.js
app.service('loginService', ["$scope", "Auth", "$firebaseAuth", function($scope,Auth,$firebaseAuth){
var vm= this;
this.login = function(user){
Auth.$authWithPassword({//on connecte l'utilisateur
email: user.email,
password: user.password
})
}
}])
and in the Ctrl:
app.controller('MainCtrl', function($scope){
loginService.login().then(function(authData) {
console.log("Utilisateur connecté:", authData.uid);
$scope.userData = authData.uid;
$location.path('#/profil');
}).catch(function(error) {
console.error("Echec connexion:", error);
$scope.errorLogin = error;
// I want return the error.code for use it in my controller
$scope.loginError = error;
});;
})
Related
I'm trying register a user in my project, but when I try to do it I get next error:
ValueError: The given username must be set
In my project I'm using Django 1.11 and AngularJS 1.6
View.py
def registrarCliente(request):
if request.method=='POST':
usuariosfinales=[]
nombre=request.POST.get('nombre')
email=request.POST.get('email')
password=request.POST.get('password')
user=User.objects.create_user(email, email, password)
user.save()
usermodelo=Usuario(usuario=user, nombre=nombre)
usermodelo.save()
userfinal=authenticate(username=email, password=password)
login(request, userfinal)
usuariosfinales.append(userfinal)
data=serializers.serialize('json', usuariosfinales)
return HttpResponse(data, content_type="application/json")
return render (request, "login/login.html")
login.html
<div class="login-wrap" id="login" ng-app="appLogin" ng-controller="conLogin">
<div class="login-right striped-bg" ng-show="Registro">
<div class="login-form">
<div class="heading">
¡Registrate!
</div>
<div class="input">
{% csrf_token %}
<div class="login-input-group spacer-field">
<span class="login-input-group-addon">
<i class="fa fa-user fa-fw"></i>
</span>
<input type="text" class="form-control" name="nombre" placeholder="Nombre" ng-model="user.nombre">
</div>
<div class="login-input-group spacer-field">
<span class="login-input-group-addon">
<i class="fa fa-at fa-fw"></i>
</span>
<input type="email" class="form-control" name="email" placeholder="Correo electrónico" ng-model="user.email">
</div>
<div class="login-input-group spacer-field">
<span class="login-input-group-addon">
<i class="fa fa-key fa-fw"></i>
</span>
<input type="password" class="form-control" name="password" placeholder="Contraseña" ng-model="user.password">
</div>
<div class="login-input-group">
<span class="login-input-group-addon">
<i class="fa fa-key fa-fw"></i>
</span>
<input type="password" class="form-control" name="password2" placeholder="Repetir contraseña">
</div>
<button class="btn btn-default btn-lg submit" type="submit" ng-click="registrar()">Registrarme</button>
</div>
</div>
</div>
</div>
appLogin.js
(function(angular) {
// body...
angular
.module('appLogin', [])
.controller('conLogin', ['$scope', '$http', function($scope, $http){
//Registro de usuario
$scope.user = {nombre:'', email:'', password:''};
$scope.registrar = function(email, password){
$http({method:'POST',
url:'/registro/',
data:{nombre: $scope.user.nombre, email: $scope.user.email, password: $scope.user.password}
}).then(
function(response2){
window.location.href='';
},function(response2){
$scope.user = response2.data || 'Request failed';
}
);
}
$scope.Ingreso = true;
$scope.Registro = false;
$scope.cambioRegistro = function(){
$scope.Ingreso = false;
$scope.Registro = true;
}
$scope.cambioIngreso = function(){
$scope.Ingreso = true;
$scope.Registro = false;
}
}])
var my_app = angular
.module('appLogin').config(
function($interpolateProvider, $httpProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.cache = true;
}
);
})(window.angular);
The debug page says me that my error is in:
user=User.objects.create_user(email, email, password)
But I don't understand why.
Take it easy please!
user = User(email = email, username= email, password =password)
user.save()
Just make sure the name SAME AS model you use.
Don't make it hard yo use
I was sending data just like this:
data:{nombre: $scope.user.nombre, email: $scope.user.email, password: $scope.user.password}
There I wasn't using $.param jquery function because I don't had jquery, I imported jquery, I changed the code above for a code with $.param just like this:
data:$.param({nombre: $scope.user.nombre, email: $scope.user.email, password: $scope.user.password})
And finally works!
The final AngularJS code is:
appLogin.js
angular
.module('appLogin', [])
.controller('conLogin', ['$scope', '$http', function($scope, $http){
//Registro de usuario
$scope.user = {nombre:'', email:'', password:''};
$scope.registrar = function(email, password){
$http({method:'POST',
url:'/cliente/registro/',
data:$.param({nombre: $scope.user.nombre, email: $scope.user.email, password: $scope.user.password})
}).then(
function(response2){
window.location.href='';
},function(response2){
$scope.user = response2.data || 'Request failed';
}
);
}
}])
its because browser using previous csrf_token, just try running 127.0.0.1:8000/your_path in private window of your browser.
im new in angularJs, im trying to make a basic login with angularJS and nodejs ( server side), i dont care about security for now im just trying to learn how to post. so i made a login form and a controller with angular :
My Login Form :
<div class="col-md-4">
<h1>Login</h2>
<form class="form" >
<div class="form-group">
<label>Username</label>
<input type="email" class="form-control" ng-model="login.mail" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" ng-model="login.password" required>
</div>
<div>
<button type="text" class="btn btn-default" ng-click="login()">Login</button>
</div>
</form>
</div>
then my router & controller Angularjs :
'use strict';
angular.module('login', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/login', {
templateUrl: 'views/login.html',
controller: 'loginCtrl'
});
}])
.controller('loginCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.login = function() {
$http.post('/api/users/login', $scope.login).success(function (response) {
console.log(response);
// refresh();
});
};
}]);
and Server side i have that :
router.post('/login/', function(req, res) {
// here "/login/" means "/users/login" ( in index of controllers)
console.log(req.body.mail);
var usermail = req.body.mail;
var pass = req.body.password;
console.log(usermail + pass);
User.find({mail: usermail}, function(err, user) {
if (err) {
res.send(err);
console.log("ça marche pas")
} else {
res.json( user );
console.log(user);
}
})
});
server side : it works ( when i use DHC chrome extension to Post) but when im using angularjs view i got that error :
POST http://localhost:3000/api/users/login 400 (Bad Request)
Please help me to solve that, i think i missed something. Thank you in advance.
I think you are sending your login function as in below line:
$http.post('/api/users/login', $scope.login)
You probably want to pass a parameter in your login function that can be sent to server as below:
$scope.login = function(loginData) {
$http.post('/api/users/login', loginData).success(function (response)
Update
You are assigning your form values to $scope.login. If you would create a separate variable for it, for example loginForm, you can send this as valid JSON to your API:
<div class="col-md-4">
<h1>Login</h2>
<form class="form" >
<div class="form-group">
<label>Username</label>
<input type="email" class="form-control" ng-model="loginForm.mail" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" ng-model="loginData.password" required>
</div>
<div>
<button type="text" class="btn btn-default" ng-click="login(loginData)">Login</button>
</div>
</form>
</div>
And .js:
.controller('loginCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.loginForm = {
mail: '',
password: ''
};
$scope.login = function(loginData) {
// Check what this prints out:
console.log(loginData);
$http.post('/api/users/login', loginData).success(function (response) {
console.log(response);
// refresh();
});
};
}]);
I am using Firebase email authentication. It worked pretty well yesterday, but for some reason, it suddenly stopped working this morning, and I have not touched the authentication part in the code at all. I am wondering if there is any changes in Firebase that i am not aware? or I did something may affect it?
Here is the code in controller:
// Home controller
.controller('LoginCtrl', ['$scope', '$firebaseAuth', function($scope, $firebaseAuth) {
// Auth Logic will be here
var firebaseObj = new Firebase("https://xxxx/");
var loginObj = $firebaseAuth(firebaseObj);
$scope.user = {};
$scope.SignIn = function(e){
e.preventDefault(); //To prevent from refresh
var email = $scope.user.username + '#whateverdomain.com';
var password = $scope.user.password;
console.log('Authentication start inside SignIn:' + );
loginObj.$authWithPassword({
email: email,
password: password
})
.then(function(user) {
//Success callback
console.log('Authentication successful');
$location.path('/dashboard');
}, function(error) {
//Failure callback
console.log(error.code);
if(error.code === "INVALID_USER") {
console.log('INVALID_USER');
$scope.loginForm.username.$invalid = true;
}
if(error.code === "INVALID_PASSWORD") {
console.log('INVALID_Password');
$scope.loginForm.password.$invalid = true;
}
});
}
}]);
Here is the view:
<body ng-controller="LoginCtrl">
<div class="container-login">
<div style="padding-bottom:0px; ">
<h1> Login</h1>
</div>
<form class="form-signin" name="loginForm" style="color:#C3BCB6;">
<div class="form-group" ng-class="{'has-error':loginForm.username.$invalid}">
<label>Username</label>
<input ng-model="user.username" type="text" name="username" class="form-control" placeholder="Input your username" ng-minlength="5" ng-maxlength="12"></input>
</div>
<div class="form-group" ng-class="{ 'has-error' : loginForm.password.$invalid }">
<label>Password</label>
<input ng-model="user.password" type="password" name="password" class="form-control" placeholder="Password" ng-minlength="8"></input>
</div>
<button type="button" ng-click="SignIn($event)" ng-disabled="!user.username || !user.password" class="btn btn-lg btn-primary btn-block">Sign in</button>
</form>
</div>
When authentication success, the user is supposed to redirect to the dashboard, or when it failed, it will show error message in the console.
Currently, it only shows "Authentication starts", but no "Authentication success" or any error message, from error.code.
I even checked out previous git commit, the authentication still did not work. Any thoughts? thanks!
I have AngularJS for front - Node.js(Express.js) for sever side web application and having trouble getting the authentication.
this is login page URL.
http://localhost:3000/#/extra-signin
After I filled email and password, and pushed login button. but still same page displayed.
URL after pushed login button is just like below.
http://localhost:3000/?email=test%40test.com&password=test#/extra-signin
I expected Angular controller would help posting login data to server by post method, but Angular controller seems not working. It seems get method working.
Angular controller:
App.controller('ExtraSigninController', function($scope, $routeParams, $http, $location, $rootScope, $alert, $window) {
$scope.login = function() {
$http.post('/auth/login',$scope.user)
.success(function(data) {
$window.localStorage.token = data.token;
var payload = JSON.parse($window.atob(data.token.split('.')[1]));
$rootScope.currentUser = payload.user;
$location.path('/');
$alert({
title: 'Cheers!',
content: 'You have successfully logged in.',
animation: 'fadeZoomFadeDown',
type: 'material',
duration: 3
});
})
.error(function() {
delete $window.localStorage.token;
$alert({
title: 'Error!',
content: 'Invalid username or password.',
animation: 'fadeZoomFadeDown',
type: 'material',
duration: 3
});
});
}
}
Angular config:
App.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/extra-signup', {
templateUrl: 'templates/states/extra-signup.html',
controller: 'ExtraSignupController'
})
.when ....
.when ....
.otherwise({
redirectTo: '/'
});
});
HTML login page:
<div id="signin-page">
<div class="page-form-wrapper"></div>
<div class="page-form">
<div class="header-content">
<h1>login</h1>
</div>
<div class="body-content">
<p>login:</p>
<div class="row mbm text-center">
<div class="col-md-4"><i class="fa fa-twitter fa-fw"></i>Twitter</div>
<div class="col-md-4"><i class="fa fa-facebook fa-fw"></i>Facebook</div>
<div class="col-md-4"><i class="fa fa-google-plus fa-fw"></i>Google +</div>
</div>
<form class="form">
<div class="form-group">
<div class="input-icon right"><i class="fa fa-user"></i>
<input type="text" placeholder="Email" name="email" ng-model="user.email" class="form-control input-lg" required autofocus/>
</div>
</div>
<div class="form-group">
<div class="input-icon right"><i class="fa fa-key"></i>
<input type="password" placeholder="password" name="password" mg-model="user.password" class="form-control input-lg" required/>
</div>
</div>
<div class="form-group pull-right">
<input type="submit" class="btn btn-success" ng-click="login()" value="login">
</div>
</form>
</div>
</div>
</div>
this is server side code:
app.post('/users/session', passport.authenticate('local'));
//passport local strategy
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
db.User.find({ where: { email: email }}).success(function(user) {
if (!user) {
// done(null, false, { message: 'Unknown user' });
res.send(401, 'User does not exist');
} else if (!user.authenticate(password)) {
// done(null, false, { message: 'Invalid password'});
res.send(401, 'Invalid email and/or password');
} else {
logger.debug('Login (local) : { id: ' + user.id + ', username: ' + user.username + ' }');
// done(null, user);
var token = createJwtToken(user);
res.send({ token: token });
}
}).error(function(err){
done(err);
});
}
));
I don't know why Angular Controller's post method doesn't work. and I don't understand why returned url is like that. Position of get parameter is something wrong.
Not sure what I am doing wrong?
Any advice would be great
I have a form that I want to trigger validation on when the user clicks submit. If the validation fails, then suitable error messages are displayed. This much works.
However if the validation passes I want the form to submit a synchronous POST request with full page reload as if the action and method parameters were set as usual.
How does one achieve trigger the normal post action (not AJAX) from the ng-submit function on the AngularJS scope?
My form of course looks basically like the following:
<form id="myForm" name="myForm" ng-submit="formAction(this, models)">
...
<input type="submit" value="Submit">
</form>
The best I can think of is to mirror the contents of the form with another hidden form submitting that one, but there must be a better way!
TO CLARIFY: If validation passes, I need the form submission to essentially behave like a normal synchronous post form submission which lands the user at the page returned by the server from the post request.
http://plnkr.co/edit/cgWaiQH8pjAT2IRObNJy?p=preview
Please check this plunkr
Basically what I am doing is passing the $event object. form is the target of the event object, and we can submit it.
function Ctrl($scope) {
$scope.list = [];
$scope.text = 'hello';
$scope.submit = function($event) {
if ($scope.text) {
$scope.list.push(this.text);
if(this.text === 'valid'){
$event.target.submit();
}
$scope.text = '';
}
};
}
Try inside formAction after you've submitted the data:
$route.reload();
I dont think you need to do a full page refresh. You have a single page app I am assuming; use it. Try something like this:
<section class="contact">
<article>
<h1>Contact</h1>
<form role="form" name="contactForm" ng-submit="formSubmit(contactForm)">
<div class="form-group">
<input class="form-control" ng-model="name" name="name" id="name" type="text" placeholder="Name" required/>
</div>
<div class="form-group">
<input class="form-control" ng-model="email" name="email" id="email" type="email" placeholder="Email Address" required/>
</div>
<div class="form-group">
<textarea class="form-control" ng-model="message" name="message" id="message" rows="5"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg">Send Message</button>
<a class="btn btn-default btn-lg" href='mailto:me#something.net'>Or email me</a>
</div>
</form>
</article>
'use strict';
MyApp.controller('ContactController', function ContactController ($scope, EmailService) {
$scope.formSubmit = function(form) {
EmailService.send(form).then(function(data) {
if(data.message.sent) {
$scope.resetForm();
alert("Message Sent");
}
else {
alert("Something went wrong. Try emailing me.");
}
});
}
$scope.resetForm = function() {
$scope.name = "";
$scope.email = "";
$scope.message = "";
}
});
MyApp.factory('AjaxService', function AjaxService ($q, $http) {
return {
http: function(ajaxParams) {
var deferred = $q.defer();
$http(ajaxParams)
.success(function (data, status, headers, config) {
deferred.resolve({
success: true,
status: status,
message: data
});
})
.error(function (data, status, headers, config) {
deferred.reject({
success: false,
status: status,
message: "Http Error"
});
});
return deferred.promise;
}
}
});
MyApp.factory('EmailService', function EmailService (AjaxService) {
return {
send: function(emailData) {
var ajaxParams = {
method: 'POST',
url: ''//where ever your form handler is,
data: {
name: emailData.name.$modelValue,
email: emailData.email.$modelValue,
message: emailData.message.$modelValue
},
cache: false
}
return AjaxService.http(ajaxParams);
}
}
});