I am trying to create an user authentication using Flask as backend and AngularJS as frontend. But I'm stuck at this error. Below is the Angular code that I am using. The login function executes successfully but also throws the following error. Please help me in solving/figuring this issue.
'use strict';
var userModule = angular.module('userModule', ['userServices']);
userModule.controller('LoginController', ['$scope', '$location', 'userAuth', function($scope, $location, userAuth) {
$scope.login = function() {
console.log("username: " + $scope.email + ", password: " + $scope.password);
// userAuth.login($scope.username, $scope.password);
// initial values
$scope.error = false;
$scope.disabled = true;
// call login from service
userAuth.login($scope.email, $scope.password)
// handle success
.then(function () {
console.log('I am in then function');
})
.catch(function () {
})
};
}]);
Error
TypeError: userAuth.login(...).then(...).catch is not a function
at Object.$scope.login (http://localhost:5000/static/js/controllers/user.js:28:13)
at http://localhost:5000/static/lib/angular/angular.js:6365:19
at Object.Scope.$eval (http://localhost:5000/static/lib/angular/angular.js:8057:28)
at Object.Scope.$apply (http://localhost:5000/static/lib/angular/angular.js:8137:23)
at HTMLFormElement.<anonymous> (http://localhost:5000/static/lib/angular/angular.js:13159:11)
at http://localhost:5000/static/lib/angular/angular.js:1992:10
at Array.forEach (native)
at forEach (http://localhost:5000/static/lib/angular/angular.js:130:11)
at HTMLFormElement.eventHandler (http://localhost:5000/static/lib/angular/angular.js:1991:5)
and my login function
function login(email, password) {
// create a new instance of deferred
var deferred = $q.defer();
// send a post request to the server
$http.get('http://' + email + ':' + password + '#localhost:5000/api/login')
// handle success
.success(function (data, status) {
if(status === 200 && data.result){
// print response
console.log('Response: ' + JSON.stringify(data))
user = true;
deferred.resolve();
} else {
// print response
console.log('Response: ' + JSON.stringify(data))
user = false;
deferred.reject();
}
})
// handle error
.error(function (data) {
// print response
console.log('Response: ' + JSON.stringify(data))
user = false;
deferred.reject();
});
// return promise object
return deferred.promise;
}
I am tired of searching and figuring this issue but didn't find anything. Don't know what's wrong :/
Any help will be appreciated.
try this
userAuth.login($scope.email, $scope.password)
.then(function () {
console.log('I am in then function');
},
function(error){
console.log('Error', error);
})
Related
I'm currently having problems with my code not calling a function in javascript. I am trying to call a function to refresh my JWT token but for some reason, it is not calling it at all.
I have added multiple debugging texts to see where it is able to run and for some reason, it will not call the function.
This is the function which is not being called. The console will never print 'Test 2 passed'
function refreshToken(store) {
console.log('Test 2 passed'); //This doesnt get displayed in the console
if(store.state.auth.isRefreshing) {
return store.state.auth.refreshingCall;
}
console.log('Test 3 passed');
store.commit('setIsRefreshing', true);
const refreshingCall = window.axios.get('/api/user/refresh-token').then(token => {
console.log('Test 4 passed');
originalRequest['Authorization'] = 'Bearer ' + token;
store.commit('setIsRefreshing', false);
store.commit('setRefreshingCall', undefined);
console.log('Token has been updated to: '+ JSON.stringify(token));
localStorage.setItem('token', token);
window.axios.defaults.headers.common['Authorization'] = 'Bearer '+ token;
store.commit('setToken', token);
console.log('Test 5 passed');
return Promise.resolve(originalRequest);
});
store.commit('setRefreshingCall', refreshingCall);
return refreshingCall;
}
This is the axios interceptor which will detect of the page returns a 401 so it can call the refresh token function
window.axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
let res = error.response;
if (res.status === 401 && res.config && !res.config.__isRetryRequest) {
// Do something with response error
alert("You're login session expired. Please log in again.")
console.log('Test 1 passed'); //This gets displayed in the console
var ret = refreshToken(this.store).then(__ => {
error.config.headers['Authorization'] = 'Bearer ' + store.state.token;
error.config.baseURL = undefined;
console.log('I have ran the last part: '+ store.state.token);
console.log('Test 6 passed');
return window.axios.request(error.config);
});
return ret;
}
return Promise.reject(error);
});
I can't seem to find why the function is not getting called, any ideas?
(Image of the console)
I am currently working on a project with AngularJS and I have a controller named "categoryController" which is looking like this:
controller('CategoryController',
[
'$scope',
'dataService',
function ($scope, dataService){
console.log("Here is working");
var getCategory = function () {
dataService.getCategory().then( // then() is called when the promise is resolve or rejected
function (response){
console.log("But this is not working");
//$scope.BooksCount = response.rowCount + ' books';
$scope.category = response.data;
},
function(err){
$scope.status = 'Unable to load data ' + err;
},
function(notify){
console.log(notify);
}
); // end of getBooks().then
};
}
]
);
So as you see, the first console.log somehow shows the message, while the second one cannot be seen in the console in the browser.
Does anyone have any idea why this function getCategory is completely ignored?
The problem is that you have only defined the getCategory function in the controller.
You also need to invoke the function
controller('CategoryController',
[
'$scope',
'dataService',
function ($scope, dataService){
console.log("Here is working");
var getCategory = function () {
dataService.getCategory().then( // then() is called when the promise is resolve or rejected
function (response){
console.log("But this is not working");
//$scope.BooksCount = response.rowCount + ' books';
$scope.category = response.data;
},
function(err){
$scope.status = 'Unable to load data ' + err;
},
function(notify){
console.log(notify);
}
); // end of getBooks().then
};
//Invoke the function
getCategory();
}
]
);
I've been struggling with handling retrieval of Spotify data in an Ionic service all day, and something that was working earlier now suddenly doesn't.
I have my login script set up in a service, and it is all working fine. However, after the console.log('updateInfo() called'); method inside updateInfo, the program will skip the rest of the function, avoiding gathering the data from Spotify.
This is the entire service so far:
.factory('SpotifyService', function ($cordovaOauth, Spotify) {
var currentUser = {},
userId = '';
function login() {
console.log('login() called');
$cordovaOauth.spotify('583ac6ce144e4fcb9ae9c29bf9cad5ef', ['user-read-private', 'playlist-read-private']).then(function (result) {
window.localStorage.setItem('spotify-token', result.access_token);
Spotify.setAuthToken(result.access_token);
}, function (error) {
console.log("Error ->" + error);
});
}
function updateInfo() {
console.log('updateInfo() called');
Spotify.getCurrentUser().then(function (data) {
console.log('Gathering data');
currentUser = data;
userId = data.id;
console.log("CURRENT USER: " + userId + " - (" + currentUser + ")");
console.log('Done updating');
});
}
return {
getUser: function () {
console.log('SpotifyService.getUser() called');
var storedToken = window.localStorage.getItem('spotify-token');
if (storedToken !== null) {
console.log('Token accepted');
currentUser = updateInfo();
console.log('getUser function returns: ' + userId + " - (" + currentUser + ")");
//currentUser = Spotify.getCurrentUser();
} else {
console.log('getUser else accessed');
login();
}
return currentUser;
}
};
})
Any ideas as to why the Spotify.getCurrentUser() method won't run?
It seems like your issue is with promises. If Spotify.getCurrentUser() returns a promise you wouldn't know what the error is because you haven't defined a catch statement. You should read Promises in Angular Explained as a Cartoon for a simple and clear explanation of promises.
Revise your code to add a catch statement:
Spotify.getCurrentUser()
.then(function (data) {
...
})
.catch(function(error){
console.log(error);
});
Every time you use promises like $cordovaOauth.spotify() or Spotify.getCurrentUser() you have to define .catch block, that will help you debugging.
Add .catch block to the getCurrentUser() function call to track down your error and i would also recommend changing error callback pattern in auth function call into .catch block as well
.catch(function(error){
console.log(error);
});
There is the following code:
angular.module('app.services', []).factory('authService', [
'SIGN_IN_ENDPOINT', 'SIGN_OUT_ENDPOINT', '$http', '$cookieStore', function(SIGN_IN_ENDPOINT, SIGN_OUT_ENDPOINT, $http, $cookieStore) {
var auth;
auth = {};
auth.signIn = function(credentials) {
return $http.post(SIGN_IN_ENDPOINT, {
user: credentials
}).then(function(response, status) {
return $cookieStore.put('user', response.data);
}, function(error) {
return console.log("Incorrect email/password");
});
};
return auth;
}
This is my module for authentication. Now I have the following function in controller:
angular.module('app.admin.controllers', []).controller('SignInController', [
'$scope', 'authService', '$state', function($scope, authService, $state) {
$scope.buttonText = "Login";
return $scope.login = function() {
$scope.buttonText = "Logging in. . .";
return authService.signIn($scope.credentials).then(function(response, status) {
return $state.go('allPosts');
}, function(err) {
$scope.invalidLogin = true;
return $scope.buttonText = "Login";
});
};
}
The problem: if I input wrong email/password, I'm waiting for 2 error callbacks - from the first 'then' from the second one, but I catch the first error callback (I can see console log) and after it THE SUCCESS callback executes! (return $state.go('allPosts')). Why? The Response from the server is 401 error.
The reason for this is, that you catch the error in the "app.services" and dont "bubble" the problem to higher tiers.
angular.module('app.services', []).factory('authService', [
'SIGN_IN_ENDPOINT', 'SIGN_OUT_ENDPOINT', '$http', '$cookieStore', function(SIGN_IN_ENDPOINT, SIGN_OUT_ENDPOINT, $http, $cookieStore) {
var auth;
auth = {};
auth.signIn = function(credentials) {
return $http.post(SIGN_IN_ENDPOINT, {
user: credentials
}).then(function(response, status) {
return $cookieStore.put('user', response.data);
}, function(error) {
console.log("Incorrect email/password");
return $q.reject(); //here is the important one.
});
};
return auth;
}
Or completely miss out the error handler.
auth.signIn = function(credentials) {
return $http.post(SIGN_IN_ENDPOINT, {
user: credentials
}).then(function(response, status) {
return $cookieStore.put('user', response.data);
});
};
If you catch the error and return a value within the error, following promises dont know about the occured error.
Since the auth service is returning the promise returned by then function, in the first error callback you need to return rejected promise.
You can do it in this way:
auth.signIn = function(credentials) {
return $http.post(SIGN_IN_ENDPOINT, {
user: credentials
}).then(function(response, status) {
return $cookieStore.put('user', response.data);
}, function(error) {
console.log("Incorrect email/password");
return $q.reject(error); // return a rejected promise;
});
};
Also remember to inject $q into your service, for this to work.
The promise returned by then is resolved with the return value of success and error callback functions.
If you do a standard return, you will always land up on the success path.
When you return $q.reject you are returning a promise that is eventually rejected. See documentation on $q.
You can also throw an exception from error callback in the service and get the same result.
I have the following project structure:
- PageController.js
- BusinessService.js
- NetworkManager.js
In my PageController I have the following call:
var getSomething = this._businessService.getMeSomething().then(function(response) {
alert("my response: " + response);
});
In my BusinessService:
getMeSometing: function() {
var user = this.getUserData();
if(user) {
var sendPromise = this._networkManager.getAnotherThing(user.id).then(function(response) {
alert("And another response: " + response);
});
} else {
$q.reject({ message: 'Rejecting this promise' });
}
},
The http calls are being made in the NetworkManager class.
So the problem here is that when I have no user data I want to break the call and so I'm using the reject.
This returns an error: Cannot read property 'then' of undefined regarding the call in PageController.
So, given my situtation, where if I have no userData, I want to cancel the request, how can I accomplish this?
Your call should return a promise. If there's a user, return the promise from getAnotherThing, otherwise, return the promise from $q.reject...
getMeSomething: function() {
var user = this.getUserData();
var sendPromise;
if(user) {
sendPromise = this._networkManager.getAnotherThing(user.id).then(function(response) {
alert("And another response: " + response);
// you probably want to return the data if successful (either response or response.data, depending on what response is)
return response.data;
});
} else {
sendPromise = $q.reject({ message: 'Rejecting this promise' });
}
return sendPromise;
}