I am supposed to check if my login has an error it will display "invalid username. then, the second login will display " server busy" and third login will redirect to link dashboard.html
However, my codes below ignore the error message and continue to dashboard.html.
How am i supposed to loop the statement so that the error will display accordingly.
postData.data._class = postData.clazz;
$timeout(function (data,status) {
$scope.isLoading = false;
if ($scope.hasError = false){
$scope.errorMessage = "Invalid username or password. Error code = " + status;
console.log($scope.errorMessage)
}
}, 2000);
$timeout(function (data,status) {
$scope.isLoading = false;
if ($scope.hasError = true){
$scope.errorMessage = "Server busy please try again later. Error code = " + status;
console.log($scope.errorMessage)
}
}, 2000);
$timeout(function (data,status) {
$scope.isLoading = false;
if ($scope.hasError = true){
$window.location.href = "/dashboard.html";
}
}, 2000);
If my understanding is correct, then you want to have 3 different results when user triggers the login function with error scenario that can be due to invalid credentials or some other issue.
If that is correct, then you can do something like following
You will need to maintain a counter that defines the attempt.
$scope.counter = 0; // This should be outside the event handler function
$timeout(function (data,status) {
$scope.isLoading = false;
if ($scope.hasError){
if($scope.counter == 0) {
$scope.errorMessage = "Invalid username or password. Error code = " + status;
console.log($scope.errorMessage);
$scope.counter++;
} else if($scope.counter == 1) {
$scope.errorMessage = "Server busy please try again later. Error code = " + status;
console.log($scope.errorMessage);
$scope.counter++;
} else {
$window.location.href = "/dashboard.html";
}
}
}, 2000);
Please note: $scope.hasError = true is assignment and NOT comparison.
Related
the function runs and console.log shows the user object on the backend. I don't understand why it's telling me there is an issue here, and really need some guidance.
vm.register = function() {
//check that passwords match
if(vm.password != vm.passwordRepeat) {
vm.registerError = "Passwords must match.";
return;
} else {
var username = vm.username;
// console.log("Valid form. Checking for existing user",username);
storeDataFactory.userExists(username).then(function(response){
//if user exists, return error
if(response.data.length > 0) {
vm.registerError = "A user with email " + username + " already exists. Please login.";
return;
} else {
//if no user exists
if(response.data.length == 0) {
// console.log("No user exists. Continue with registration.");
}
//assign info to user object
var user = {
username: vm.username,
password: vm.password,
name: vm.name,
phone: vm.phone
};
**storeDataFactory.createUser(user).then(function(response){**
vm.user = response.data;
console.log("Created user", vm.user);
if(response.data.length > 0) {
console.log("Created user", vm.user);
vm.registerMessage = "Successful registration, please login";
vm.registerError = null;
vm.user = response.data;
}
}).catch(function(error){
console.log(error);
vm.registerError = "There was an error creating your account.";
vm.registerMessage = null;
});
}
});
}
};
The backend code:
module.exports.register = function(req, res) {
console.log('registering user', req.body);
//create the user object with hashed pass
User
.create({
username: req.body.username,
name: req.body.name,
phone: req.body.phone,
password: bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(10))
}, function(err, user) {
if (err) {
console.log("Error creating account");
res
.status(400)
.json(err);
} else {
console.log("Account created!", user);
res
.status(201)
.json(user);
}
});
};
Account created! and the user object are logged on the backend. It just won't display that damn Successful Registration! Please login. message.
storeDataFactory code:
/* global angular */ angular.module('rumbleApp').factory('storeDataFactory', storeDataFactory);
function storeDataFactory($http) {
return {
userExists: userExists,
createUser: createUser
};
function userExists(username) {
return $http.get('/api/users/userExists/' + username).then(complete).catch(failed);
}
function createUser(user) {
$http.post('/api/users/register', user).then(complete).catch(failed);
}
function complete(response) {
return response;
}
function failed(error) {
console.log(error.statusText);
return "There was an error with the API call.";
}
}
Are you sure you're returning from storeDataFactory.createUser()? Can you post the code for that method?
Sounds like the code is executing, but you're not returning anything from it (hence why it thinks it's undefined)
I am new to Angular and I am trying to add data from forum into the database, to do so i need the id of the current user which i get with no problem, only in my post method I rely entirely on the data that i get from the forum, but in the forum i wouldn't of course ask for the id to be filled so I need to add it automatically to my controller and i don't know how to do so : here is the function that I use in my controller :
app.addFT = function () {
//Get the current user Id
Auth.getUser().then(function (data) {
console.log(data.data.email);
Compte.getComptebymail(data.data.email).then(function(result)
{
console.log(result.data.col.IdCollaborateur);
lecollaborateur.push(result.data.col);
$scope.lecollaborateur = lecollaborateur;
});
});
console.log(app.addData);
//we connect it to the back end of the application
FT.createFT(app.addData).then(function (data) {
if(data.data.success){
//create success message
app.loading = false;
app.successMsg = data.data.message + '...Redirection';
//Redirect to show projet
$timeout(function () {
$location.path('/FeuillesTempsListe');
}, 2000);
}else{
//create an error message
app.loading = false;
app.errorMsg = data.data.message;
}
});
};
app.addData is the data the user fills in the view : I get the name,description,...but I don't know how to pass the Id to app.addData other then using the forum, I tried :
app.addData.Id=lecollaborateur.Id; but it's not working , any suggestions ?
You need call createFT only after the success call of getComptebymail.
So that you will have id in the app.addData.
app.addFT = function() {
//Get the current user Id
Auth.getUser().then(function(data) {
console.log(data.data.email);
Compte.getComptebymail(data.data.email).then(function(
result) {
console.log(result.data.col.IdCollaborateur);
lecollaborateur.push(result.data.col);
$scope.lecollaborateur = lecollaborateur;
app.addData.Id = lecollaborateur.Id;
console.log(app.addData);
//we connect it to the back end of the application
FT.createFT(app.addData).then(function(data) {
if (data.data.success) {
//create success message
app.loading = false;
app.successMsg = data.data.message +
'...Redirection';
//Redirect to show projet
$timeout(function() {
$location.path(
'/FeuillesTempsListe'
);
}, 2000);
} else {
//create an error message
app.loading = false;
app.errorMsg = data.data.message;
}
});
});
});
};
I need to return a rejected promise from a js function. I am using angular $q as you can see. But it doesn't work.
In function getDBfileXHR, when the promise getDBfileXHRdeferred is rejected using getDBfileXHRdeferred.reject() I would to pass into the the error case of the function getDBfileXHR and run fallbackToLocalDBfileOrLocalStorageDB(). But it doesn't work.
Is there a syntax error ?
I am a bit new to promises.
Thanks
this.get = function () {
var debugOptionUseLocalDB = 0,
prodata = [],
serverAttempts = 0;
if (debugOptionUseLocalDB) {
return fallbackToLocalDBfileOrLocalStorageDB();
}
if (connectionStatus.f() === 'online') {
console.log("Fetching DB from the server:");
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function () { // success
console.log('-basic XHR request succeeded.');
return dbReadyDeferred.promise;
}, function () { // error
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
});
}
}
function getDBfileXHR(url, serverAttempts) {
var getDBfileXHRdeferred = $q.defer(),
request = new XMLHttpRequest();
if (typeof serverAttempts !== "undefined") serverAttempts++;
request.open("GET", url, true); //3rd parameter is sync/async
request.timeout = 2000;
request.onreadystatechange = function () { // Call a function when the state changes.
if ((request.readyState === 4) && (request.status === 200 || request.status === 0)) {
console.log('-we get response '+request.status+' from XHR in getDBfileXHR');
var jsonText = request.responseText.replace("callback(", "").replace(");", "");
if (jsonText === '') {
console.error('-error : request.status = ' + request.status + ', but jsonText is empty for url=' + url);
if (serverAttempts <= 2){
sendErrorEmail("BL: jsonText is empty, trying to reach server another time", 11);
getDBfileXHR(url, serverAttempts);
return;
} else {
sendErrorEmail("BL: jsonText is empty and attempted to reach server more than twice", 14);
var alertPopup = $ionicPopup.alert({
title: 'Error '+"11, jsonText is empty",
template: "Sorry for the inconvenience, a warning email has been sent to the developpers, the app is going to restart.",
buttons: [{
text:'OK',
type: 'button-light'
}]
});
getDBfileXHRdeferred.reject();
}
} else {
}
} else {
console.error('-error, onreadystatechange gives : request.status = ' + request.status);
getDBfileXHRdeferred.reject();
}
};
if (url === "proDB.jsonp") {
console.log("-Asking local proDB.json...");
} else {
console.log("-Sending XMLHttpRequest...");
}
request.send();
return getDBfileXHRdeferred.promise;
}
EDIT:
I rewrote my function using this approach. It seems better and cleaner like this. But now can you help me handle the multiple attempds ?
function getDBfileXHR(url, serverAttempts) {
return new Promise(function (resolve, reject) {
var request = new XMLHttpRequest();
request.open("GET", url, true); request.timeout = 2000;
var rejectdum;
if (url === "proDB.jsonp") {
console.log("-Asking local proDB.json...");
} else {
console.log("-Sending XMLHttpRequest...");
}
request.onload = function () {
if ( (request.readyState === 4) && (request.status === 200 || request.status === 0) ) {
console.log('-we get response '+request.status+' from XHR in getDBfileXHR');
var jsonText = request.responseText.replace("callback(", "").replace(");", "");
if (jsonText === '') {
console.error('-error : request.status = ' + request.status + ', but jsonText is empty for url=' + url);
sendErrorEmail("BL: jsonText is empty, trying to reach server another time", 11);
sendErrorEmail("BL: jsonText is empty and attempted to reach server more than twice", 14);
var alertPopup = $ionicPopup.alert({
title: 'Error '+"11, jsonText is empty",
template: "The surfboard database could not be updated, you won't see the new models in the list, sorry for the inconvenience.",
buttons: [{
text:'OK',
type: 'button-light'
}]
});
console.log('oui on passe rejectdum')
rejectdum = 1;
reject({
status: this.status,
statusText: request.statusText
});
} else {
var parsedJson;
try {
parsedJson = JSON.parse(jsonText);
} catch (e) {
console.warn("Problem when trying to JSON.parse(jsonText) : ");
console.warn(e);
console.warn("parsedJson :");
console.warn(parsedJson);
}
if (parsedJson) {
var prodata = jsonToVarProdata(parsedJson);
console.log('-writing new prodata to localStorage');
console.log('last line of prodata:' + prodata[prodata-1]);
storageService.persist('prodata', prodata);
storageService.store('gotANewDB', 1);
}
resolve(request.response);
dbReadyDeferred.resolve();
}
}
};
request.onerror = function () {
reject({
status: this.status,
statusText: request.statusText
});
};
request.send();
});
}
Is it a clean way to do this to do several attempts :
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function () { // success
console.log('-basic XHR request succeeded.');
return dbReadyDeferred.promise;
})
.catch(function (){
if (typeof serverAttempts !== "undefined") serverAttempts++;
console.log('on passe dans le catch, serverAttempts = ', serverAttempts)
if (serverAttempts < 2) {
return getDBfileXHR(dbUrl(), serverAttempts)
.then(function () { // success
console.log('-basic XHR request succeeded.');
return dbReadyDeferred.promise;
})
.catch(function (){
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
})
} else {
console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
return fallbackToLocalDBfileOrLocalStorageDB();
}
})
if you remove the code to retry (twice?) on failure your code would possibly work (haven't looked into that) -
the issue is, the only promise your calling code gets is that of the first attempt. If the first attempt fails, that promise is never resolved or rejected
You need to resolve the promise with the promise returned by getDBfileXHR(url, serverAttempts); - so, something like
if (serverAttempts <= 2){
sendErrorEmail("BL: jsonText is empty, trying to reach server another time", 11);
getDBfileXHRdeferred.resolve(getDBfileXHR(url, serverAttempts));
return;
} else {
Because if promise(1) resolves to a rejected promise(2), the result is that promise(1) rejects with the rejection value of promise(2)
This is how native Promises, and many many Promise/A+ compliant libraries work,
so this should be the case with $.defer if it follows the Promise/A+ spec
I'm facing one issue with a registration form.
If I log in and browser offers me to save username/password, they are both displayed on the registration form.
I tried to reset the form, I tried to set user details to null, but it didn't work.
As username and password are predefined, repeat password error is present.
here is a snap
Register Controller
...
registerController.$inject = ['$location', 'UsersService', '$timeout'];
function registerController($location, UsersService, $timeout) {
var vm = this;
vm.master = {};
vm.isValid = false;
vm.error = false;
vm.errorMessage = "";
vm.user = {
username : '',
password : '',
email: ''
}
formReset();
// function to submit the form after all validation has occurred
vm.submitForm = function(isValid) {
// check to make sure the form is completely valid
if (isValid) {
console.info('form valid');
vm.isValid = true;
}
if(vm.isValid === true){
signup();
}
else{
vm.error = true;
vm.errorMessage = "All fields are required";
}
};
function signup() {
// initial values
vm.error = false;
vm.success = false;
var username = vm.user.username;
var password = vm.user.password;
// call register from service
UsersService.register(username, password)
// handle success
.then(function () {
vm.success = true;
vm.successMessage = "Registrations successful.You'll get confirmation email soon and you can proceed with login";
$timeout(function() {
$location.path('/login');
}, 5000);
})
// Catch error
.catch(function (fallback) {
vm.error = true;
vm.errorMessage = fallback;
});
};
function formReset(form){
if(form === '' || form === undefined){
form = vm.form;
}
if(form){
form.$setPristine();
form.$setUntouched();
form.$setValidity();
}
vm.contact = angular.copy(vm.master);
}
}
jade template
form.form-horizontal.col-md-12(name="form" role="form", data-ng-submit="ctrl.submitForm(form.$valid)", method="post" novalidate, autocomplete="off")
.form-group(show-errors)
label.control-label.col-xs-3 Username
span.icon-req.glyphicon.glyphicon-asterisk
.col-xs-9
input.form-control(type="text", name="username", placeholder="Enter Username", data-ng-model="ctrl.user.username", data-user-id="{{ctrl.user._id}}", data-ng-minlength="3", required="required" auth-username)
span.help-inline.error(data-ng-show = "form.$dirty && form.username.$error.required") Username required
span.help-inline.error(data-ng-show = "form.$dirty && form.username.$error.minlength") Username too short
span.help-inline.error(data-ng-show = "ctrl.form.username.$touched && ctrl.form.username.$error.usernameExists") Username already taken
.form-group(show-errors)
label.control-label.col-xs-3 Password
span.icon-req.glyphicon.glyphicon-asterisk
.col-xs-9
input.form-control(type="password", name="password", placeholder="Password", data-ng-model="ctrl.user.password", data-ng-minlength="6",ng-maxlength="16", required="required")
span.help-inline.error(data-ng-show = "form.$dirty && form.password.$error.required") Password required
span.help-inline.error(data-ng-show = "form.$dirty && form.password.$error.minlength || form.password.$error.maxlength") Password must be 6-16 character long
.form-group(show-errors)
label.control-label.col-xs-3 Repeat password
span.icon-req.glyphicon.glyphicon-asterisk
.col-xs-9
input.form-control(type="password", name="repeatPassword", placeholder="Repeat Password", data-ng-model="ctrl.user.repeatPassword", data-ng-minlength="4",required="required", equal-to="ctrl.user.password")
span.help-inline.error(data-ng-show = "form.$dirty && form.repeatPassword.$error.equalTo") Password must be equal
....
button.btn.btn-default(type="submit") Submit
a(href='/')
button.btn.btn-primary(type="button") Cancel
I'm pretty much new to mean stack development, and I'm sure I miss something out.I appreciate your help. Thanks
PS: the code posted is a simplified and not optimized one
So first I try with the HTML autocomplete Attribute. But it was not working on chrome. After that I found this post Chrome Browser Ignoring AutoComplete=Off.
One of the solution to disable autocomplete is to set the input readonly and add a bit of js on the onfocus Attribute.
onfocus="this.removeAttribute('readonly')
I test this solution with an angular form and it's working.
See the original fiddle by fizzix
I have a registration dialog where when the user enters username and password I need to check the DB whether the user is present
or not. But when I am validation for the same my call does not hold back until I get the results from the server.
After searching for a while I got to know about callbacks. So I have added a call back inside this.isUser method.
And it is successful. But now doRegistration method is not synchronous with the isUser method.
How to make all my calls synchronous?
this.doRegistration = function(uname, pwd, confirmPwd) {
if(this.isUser(uname)) {
return "USER_EXISTS";
} else {
saveUser(uname, pwd);
return "SUCCESS";
}
};
this.isUser = function(username) {
var users = new Array();
getAllUsers('param', function(response) {
users = response;
console.log(users.length);
for(i = 0; i < users.length; i++) {
if(users[i].username === username) {
return true;
}
}
return false;
});
};
function getAllUsers(param, callback) {
loginFactory.AllUsers.query(function(response) {
if(response != undefined && response.length > 0) {
callback(response);
}
});
}
You may rewrite the code like following:
this.doRegistration = function(uname, pwd, confirmPwd, callBack) {
this.isUser(uname,function(flag) {
if(flag){
callBack("USER_EXISTS");
}
else {
saveUser(uname, pwd, function(err,result){
if(err){
callBack("SAVING_FAILED");
}
else {
callBack("SUCCESS");
}
});
}
});
};
this.isUser = function(username,callBack) {
var users = new Array();
getAllUsers('param', function(response) {
users = response;
console.log(users.length);
for(i = 0; i < users.length; i++) {
if(users[i].username === username) {
callBack(true);
}
}
callBack(false);
});
};
function saveUser(userName, pwd, callBack){
//code to save user
//chek for error in saving
if(err){
callBack(err,null)
}
else {
callBack(null, "success")
}
}
function getAllUsers(param, callback) {
loginFactory.AllUsers.query(function(response) {
if(response != undefined && response.length > 0) {
callback(response);
}
});
}
You may also define saveUser as a function with callback. Here it wont wait for saveUser method to complete.