I'm building my (first) angular app that will have tokens inserted into headers (the content shown is for the most part taken from here)
angular.module('myApp')
.factory('sessionInjector', ['SessionService', function(SessionService) {
var sessionInjector = {
request: function(config) {
config.headers['x-session-token'] = SessionService.getToken();
return config;
}
};
return sessionInjector;
}])
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('sessionInjector');
}])
The trouble I'm having is with SessionService - how can I initialize this with call to the server?
For example, this didn't work:
.factory('SessionService', ['$injector', function($injector){
var token = "";
return {
getToken: function () {
var http = $injector.get('$http');
if (token === "") {
http.get('http://localhost/api/auth/getToken').success(function (ret) {
token = ret;
});
}
return token;
//I can see a $q/deferred/promise should be used somehow here...
//but I'm not sure it solves the problem I'm having...
}
}
}]);
because it just overloads my cpu to 100%...
Since it's my first angular app, I'm sure I'm missing something, but... what?
EDIT:
Another take on the matter... still doesn't work though... (again, uses up cpu, probably infinite loop)
.factory('sessionData', function () {
var currentToken = '[uninitialized-token]';
return {
getToken: function () {
return currentToken;
},
setToken: function (token) {
currentToken = token;
}
}
})
.factory('sessionInjector', ['sessionData', '$injector', '$q', function (sessionData, $injector, $q) {
var sessionInjector = {
request: function (config) {
var deferred = $q.defer();
var http = $injector.get('$http');
http.get('http://localhost/api/auth/getToken').success(function (ret) {
sessionData.setToken(ret);
console.log("successfully authenticated with token " + sessionData.getToken());
config.headers['x-header-sessionID'] = sessionData.getToken();
deferred.resolve(config);
})
.error(function(){
console.log("failed to authenticate");
deferred.resolve(config);
});
return deferred.promise;
}
};
return sessionInjector;
}])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push('sessionInjector');
}])
.run(['$http', 'sessionData', function ($http, configs, sessionData) {
$http.get('http://localhost/api/auth/testMethod').then(function (ret) {
//do something...
});
}])
Check whether this modified code fragment will solve your issues.
.factory('SessionService', ['$http', '$q', function($http, $q) {
var token = null;
var sessionService = {};
var differred = $q.defer();
sessionService.readToken = function() {
return $http.get('http://localhost/api/auth/getToken')
.success(function (res) {
console.log('Auth Success and token received: ' + JSON.stringify(res.data));
// Extract the token details from the received JSON object
token = res.data;
differred.resolve(res);
}, function (res) {
console.log('Error occurred : ' + JSON.stringify(res));
differred.reject(res);
}
)
};
sessionService.getToken = function() {
return token;
};
sessionService.isAnonymous = function() {
if (token)
return true;
else
return false;
};
return sessionService;
}])
.factory('sessionInjector', ['SessionService', function(SessionService) {
var sessionInjector = {
request: function(config) {
if (!sessionService.isAnonymous) {
config.headers['x-session-token'] = SessionService.getToken();
return config;
}
}
};
return sessionInjector;
}])
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('sessionInjector');
}])
Answer was actually pretty straight forward - if the targeted URL is for login, then don't inject anything (look for the comment the fix):
.factory('sessionData', function () {
var currentToken = '[uninitialized-token]';
return {
getToken: function () {
return currentToken;
},
setToken: function (token) {
currentToken = token;
}
}
})
.factory('sessionInjector', ['sessionData', '$injector', '$q', function (sessionData, $injector, $q) {
var sessionInjector = {
request: function (config) {
//The fix:
if(config.url === 'http://localhost/api/auth/getToken')
return config;
var deferred = $q.defer();
var http = $injector.get('$http');
http.get('http://localhost/api/auth/getToken').success(function (ret) {
sessionData.setToken(ret);
console.log("successfully authenticated with token " + sessionData.getToken());
config.headers['x-header-sessionID'] = sessionData.getToken();
deferred.resolve(config);
})
.error(function(){
console.log("failed to authenticate");
deferred.resolve(config);
});
return deferred.promise;
}
};
return sessionInjector;
}])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push('sessionInjector');
}])
.run(['$http', 'sessionData', function ($http, configs, sessionData) {
$http.get('http://localhost/api/auth/testMethod').then(function (ret) {
//do something...
});
}])
Related
Upgrade to angularjs version 1.7 and this code does not compile
app.factory('LoginService', function ($http) {
return {
login: function (param, callback) {
$http.post(url, param)
.success(callback)
.error(function (data, status, headers, config) {
});
}
};
});
On the controller I make the call to the service LoginService
function LoginController($http, $location, LoginService, blockUI) {
var vm = this;
LoginService.usuario(
{login: vm.username, clave: vm.password},
function (data, status, headers, config) {
vm.resultado = data;
if (vm.resultado == "True") {
window.location = "/Home/Index";
} else {
vm.error = 'Usuario o password incorrecto';
}
});
};
I want to know how the function is called from the controller because it implemented the http.post service using .then
app.factory('LoginService', function ($http) {
return {
login: function (data) {
$http.post(url, data)
.then(function (resultado) {
debugger;
if (resultado.data === "True") {
return resultado.data;}
else {
console.log("NO");}
});
}};
});
I suggest you get familiar with a AngularJS $q service and its Promise API.
You LoginService.login(...) method should return the Promise from $http.post(...):
app.factory('LoginService', function ($http) {
return {
login: function (data) {
return $http.post(url, data)
.then(function(response) {
return response.data;
});
});
Then, your Controller can access the returned data via the resolved Promise:
function LoginController(LoginService) {
var vm = this;
LoginService.login({login: vm.username, clave: vm.password})
.then(function (result) {
// handle result here...
});
the solution would be this:
function LoginController($scope,$window,$q,LoginService) {
$scope.fnBusqueda = function () {
var promesas = [
obtenerLogin()
];
$q.all(promesas).then(function (promesasRes) {
var oArrayResponse = promesasRes;
if ((oArrayResponse.length > 0)) {
$scope.respuesta = oArrayResponse[0];
if ($scope.respuesta == "True") {
window.location = "/Home/Index";
} else {
$cope.error = 'Usuario o password incorrecto';
}
}
});
};
function obtenerLogin() {
var defered = $q.defer();
var promise = defered.promise;
LoginService.login(url_valida_login, '{login:X,clave:X}').then(function (response) {
defered.resolve(response);
}).catch(function (data) {
defered.resolve([]);
})
return promise;
}
}
I'm trying to use Django REST Framework's token-based authentication scheme with an AngularJS client. I'm able to successfully retrieve and store a token from the server, but I'm having trouble figuring out how to attach the token to subsequent responses. Here's the service that manages logging in and saving a token:
angular.module('mymodule')
.factory('loginService', function ($http, $window) {
var api_base = "link to my api";
return {
async: function() {
return $http.get(api_base + "authentication/login/").then(function (response) {
return response.data;
}, function errorCallback(response) {
console.log("Testuser API Error: " + response);
return null;
});
},
loginUser: function(email, password) {
self.saveToken = function(auth_token) {
$window.localStorage['jwtToken'] = auth_token;
};
self.getToken = function() {
return $window.localStorage['jwtToken'];
};
console.log("...to listing " + email);
return $http.post("link to my api/authentication/login/", {
email: email,
password: password
}).then(function(response) {
if(response.config.url.indexOf("link to my api") === 0 && response.data.auth_token) {
self.saveToken(response.data.auth_token);
}
return response;
});
}
};
});
Here's the controller associated with the above service to handle logging in:
angular.module('mymodule').controller("LoginController", function(loginService, $scope) {
$scope.loginusers = [];
$scope.refresh = function() {
loginService.async().then(function(data) {
if (data == null)
return;
console.log(data[0]["email"]);
$scope.loginusers = [];
for (var loginuser in data)
$scope.loginusers.push(loginuser);
});
};
$scope.refresh();
// Test //
$scope.loginTestUser = function() {
console.log("something...");
loginService.loginUser(
$scope.email,
$scope.password
)
};
//////
});
And here's the service that I'd like to use for displaying a user's profile after the token is sent back to the server.
angular.module('mymodule').factory("profileService", function($http, loginService, $httpProvider) {
var api_base = "link to my api";
$httpProvider.interceptors.push(function($q, $window) {
return {
'request': function(config) {
config.headers['Token'] = $window.localStorage['jwtToken'];
return config;
}
};
});
return {
async: function() {
return $http.get(api_base + "authentication/me/").then(function (response) {
return response.data[0];
}, function errorCallback(response) {
console.log("Profile API Error: " + response);
return null;
});
}
};
});
How should I be approaching this?
Newbie to angular, using service I'm trying to load cachefactory and using the cache from controller.
Here is service methods
codesApp.service('CodeFilterService',function($filter, $http, CacheService,$log){
this.getByCodeType = function (codeTypeValue, codeName) {
if (angular.isUndefined(CacheService.get('Codes'))) {
loadCodes();
}
return $filter('filter')(CacheService.get('Codes'), {codetype: codeTypeValue, name: '!' + codeName});
};
this.getAllCodes = function () {
$log.info("getAllCodes");
if (angular.isUndefined(CacheService.get('Codes'))) {
$log.info("Loading fresh getAllCodes");
this.loadCodes();
}
return CacheService.get('Codes');
};
this.loadCodes = function () {
$http.get("./rest/codes").then(function (response) {
$log.info("Codes Size" +response.data.length );
CacheService.put('Codes', response.data);
});
};
});
codesApp.factory('CacheService',function($cacheFactory){
return $cacheFactory('super-cache');
});
Controller Code :
codesApp.controller('CodeCreateController',function($scope,$state,
Code,CodeFilterService,$log){
...
$scope.codeDropdownList = CodeFilterService.getAllCodes();
$log.info("codeDropdownList = " + angular.isUndefined($scope.codeDropdownList)) ;
});
Here angular.isUndefined($scope.codeDropdownList)) returns true which means data not getting loaded. Is there any way to resolve this issue.
You may use promise inject $q
codesApp.service('CodeFilterService', function ($filter, $http, CacheService, $log, $q) {
this.getByCodeType = function (codeTypeValue, codeName) {
if (angular.isUndefined(CacheService.get('Codes'))) {
loadCodes();
}
return $filter('filter')(CacheService.get('Codes'), {
codetype: codeTypeValue,
name: '!' + codeName
});
};
this.getAllCodes = function () {
$log.info("getAllCodes");
var deferred = $q.defer();
if (angular.isUndefined(CacheService.get('Codes'))) {
$log.info("Loading fresh getAllCodes");
this.loadCodes().then(function (result) {
$log.error('getAllCodes success');
var cachedCodes = CacheService.get('Codes');
deferred.resolve(cachedCodes);
}, function (reason) {
$log.error('getAllCodes error: ' + reason);
deferred.reject();
});
} else {
var cachedCodes = CacheService.get('Codes');
deferred.resolve(cachedCodes);
}
return deferred.promise;
};
this.loadCodes = function () {
$log.info("loadCodes");
var deferred = $q.defer();
$http.get("./rest/codes").then(function (response) {
$log.error('loadCodes success');
$log.info("Codes Size" + response.data.length);
CacheService.put('Codes', response.data);
deferred.resolve();
}, function (reason) {
$log.error('loadCodes error: ' + reason);
deferred.reject();
});
return deferred.promise;
};
});
codesApp.controller('CodeCreateController', function ($scope, $state,
Code, CodeFilterService, $log) {
...
CodeFilterService.getAllCodes().then(function (result) {
$log.info('result: ' + result);
$scope.codeDropdownList = result;
$log.info("codeDropdownList = " + angular.isUndefined($scope.codeDropdownList))
}, function (reason) {
$log.error('error: ' + reason);
});
});
This the factory.
latModule.factory('latSvc',
[
"$http", "$scope", "$q",
function($http, $scope, $q) {
console.log("Enter latUserReportDateSvc");
return {
getPromiseForUserReportDate: function () {
$scope.userId = "bpx3364";
var deferred = $q.defer();
$http.get('/api/UserReportStatusApi', { 'userId': $scope.userId }).then(function(reponse) {
deferred.resolve(reponse);
},
function(error) {
deferred.reject(error);
});
return deferred.promise;
},
getPromiseForLocation: function () {
$scope.userId = "bpx3364";
var deferred = $q.defer();
$http.get('api/UserAccountApi/', { 'userId': $scope.userId }).then(function (reponse) {
deferred.resolve(reponse);
},
function (error) {
deferred.reject(error);
});
return deferred.promise;
},
getPromiseForErrorSummary: function (userInfoVm) {
console.log("latErrorSummarySvc getErrorCounts, userInfo: ", userInfoVm);
$scope.userId = "bpx3364";
$scope.serviceTypeCode = 4;
var deferred = $q.defer();
$http.get('/api/UserReportStatusApi', { 'userId': $scope.userId, 'serviceTypeCode': $scope.serviceTypeCode }).then(function (reponse) {
deferred.resolve(reponse);
},
function (error) {
deferred.reject(error);
});
return deferred.promise;
}
};
}
]);
This is the controller
latModule.controller("dashboardController",
["$scope","latSvc",
function ($scope,latSvc) {
console.log("enter dashboard controller");
console.log("scope: ", $scope);
console.log("homeUserInfo: ", $scope.homeLatUserInfo);
var dashboardUserReportDate = function() {
latSvc.getUserReportDateInfo().then(
function(response) {
$scope.dashboardUserReportDateData = response;
}, function(error) {}
);
};
dashboardUserReportDate();
var dashboardErrorCounts = function() {
latSvc.getPromiseForErrorSummary($scope.homeLatUserInfo).then(
function(response) {
$scope.dashboardErrorCountsData = response;
},
function (error) { }
);
};
dashboardErrorCounts();
var dashboardAtmCount = function() {
latSvc.getPromiseForLocation().then(
function(response) {
$scope.dashboardAtmCountData = response;
}, function(error) {}
);
};
dashboardAtmCount();
}]);
after running this code I am getting an unknown provider error while I am trying to implement this promise concept.Because while I was calling through service with out resolving promise and without using then the url was getting hit multiple times.
You can't use / inject $scope into a service.
But as far as I understand your code you should be fine using local variables for your http request query parameters.
And Vineet is right - you should return the $http.get() directly (it's already a promise).
I have following controller which is posting a new user and also getting new users.
The problem here is after adding a new user, the scope is not updated so view is not affected. I have also tired returning the function so it expects a promise but didnt update the scope.
myapp.controllers('users', ['usersService', ''$scope',', function(usersService, $scope){
getUsers();
function getUsers(params) {
if (typeof(params) === "undefined") {
params = {page: 1};
}
usersService.getUsers(params).then(function (res) {
$scope.users = res.items;
$scope.usersListTotalItems = res._meta.totalCount;
$scope.usersListCurrentPage = res._meta.currentPage + 1;
});
}
}
$scope.addUser = function (user) {
usersService.adddNewUser(user).then(function (response) {
getUsers();
});
}
}]);
myApp.factory('userService', ['Restangular', '$http', function (Restangular, $http) {
return {
getUsers: function (params) {
var resource = 'users/';
var users = Restangular.all(resource);
return users.getList(params)
.then(function (response) {
return {
items : response.data[0].items,
_meta : response.data[0]._meta
}
});
},
adddNewUser: function (items) {
var resource = Restangular.all('users');
var data_encoded = $.param(items);
return resource.post(data_encoded, {}, {'Content-Type': 'application/x-www-form-urlencoded'}).
then(function (response) {
return response;
},
function (response) {
response.err = true;
return response;
});
}
};
}]);
I think it is a small error however you did not include $scope in the argument for the controller function.
myapp.controllers('users', ['usersService','$scope', function(usersService $scope){
getUsers();
function getUsers(params) {
if (typeof(params) === "undefined") {
params = {page: 1};
}
usersService.getUsers(params).then(function (res) {
$scope.users = res.items;
$scope.usersListTotalItems = res._meta.totalCount;
$scope.usersListCurrentPage = res._meta.currentPage + 1;
});
}
}
$scope.addUser = function (user) {
usersService.adddNewUser(user).then(function (response) {
getUsers();
});
}
}]);