Configure angular $http with a value obtained from server - angularjs

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

AngularJS 1.7 - HTTP POST

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;
}
}

Sending an access token to server using AngularJS

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?

Angularjs controller fails to load http data from cachefactory service

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);
});
});

While returning promise it gives me an unknown provider error

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).

$scope is not updated after database trigger

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();
});
}
}]);

Resources