Can't update vars inside Angularjs Factory - javascript

Anyone can help with this? Can't update var ABCKey. Execute setAuthenticatedAccount and console.log return correct value. After that, run getAuthenticatedAccount, and receive undefined.
angular.module('authentication.service', [
])
.factory('Authentication', ['$state', '$cookies', '$http', 'app', 'routes', 'cfCryptoHttpInterceptor',
function($state, $cookies, $http, app, routes, cfCryptoHttpInterceptor) {
var ABCKey;
var setAuthenticatedAccount = function (account, tokenAuth) {
var accountInfo = {'email': account.email, 'username': account.username, 'token': tokenAuth}
var abc = CryptoJS.enc.Base64.parse(account.abc);
Authentication.setABCKey(abc);
console.log(Authentication.showABCKey())
}
var getAuthenticatedAccount = function() {
if(!$cookies.authenticatedAccount) {
return;
}
console.log(Authentication.showABCKey())
}
var setABCKey = function(key) {
ABCKey = key;
};
var showABCKey = function() {
return ABCKey;
};
var Authentication = {
setAuthenticatedAccount: setAuthenticatedAccount,
getAuthenticatedAccount: getAuthenticatedAccount,
setABCKey: setABCKey,
showABCKey: showABCKey
};
return Authentication;
}]);

Remove Authentication while you are calling your functions because it is creating object every time. And also set var ABCKey=null at the time of decelaration like this-
angular.module('authentication.service', [
])
.factory('Authentication', ['$state', '$cookies', '$http', 'app', 'routes', 'cfCryptoHttpInterceptor',
function($state, $cookies, $http, app, routes, cfCryptoHttpInterceptor) {
var ABCKey=null;
var setAuthenticatedAccount = function (account, tokenAuth) {
var accountInfo = {'email': account.email, 'username': account.username, 'token': tokenAuth}
var abc = CryptoJS.enc.Base64.parse(account.abc);
setABCKey(abc);
console.log(showABCKey())
}
var getAuthenticatedAccount = function() {
if(!$cookies.authenticatedAccount) {
return;
}
console.log(showABCKey())
}
var setABCKey = function(key) {
ABCKey = key;
};
var showABCKey = function() {
return ABCKey;
};
var Authentication = {
setAuthenticatedAccount: setAuthenticatedAccount,
getAuthenticatedAccount: getAuthenticatedAccount,
setABCKey: setABCKey,
showABCKey: showABCKey
};
return Authentication;
}]);

dont use var its single tone class you need to define ABCkey in this
var ABCKey;
try with this
this.ABCKey = '';

Related

Pass variable from config to factory in AngularJS and UI Router

I'm trying to make a search in an http call with a different value depending on the view that I'm in.
My factory looks like this:
.factory('SearchService', ['$http','$filter', function($http, $filter) {
var service = {
getAllExhibitors : function () {
var searchindex = 'Berliner';
var url = '...';
var config = {
params: {
search: searchindex
},
cache:true
};
$http.get(url, config).then(function (data) {
service.datafairs = data.data.rows;
...
});
}...
As you can see I'm passing a hardcoded variable searchindex as parameter for the search.
Could I set this variable depending on the view I'm in?
My config for the router looks like this:
.config(function($stateProvider) {
var berlinerState = {
name: 'berliner',
url: '/berlinerliste/',
views: {
'header': {
templateUrl: 'header.htm'
},
'main':{
templateUrl: 'bl2017.htm'
}
}
}
var koelnerState = {
name: 'koelner',
url: '/koelnerliste/',
views: {
'header': {
templateUrl: 'header.htm'
},
'main':{
templateUrl: 'kl2017.htm'
}
}
}
...
For example, that on /berlinerliste, searchindex = X and on /koelnerliste, searchindex = Y
Any tips?
From the controller when you call your factory, you could be pass the actual state name and based on this value define the searchIndex on the getAllExhibitors method.
getAllExhibitors : function (stateName) {
var searchindex = '';
var url = '...';
var config = {
params: {
search: searchindex
},
cache:true
};
if(stateName === 'berliner'){
config.params.search = 'asdf'
}
....
$http.get(url, config).then(function (data) {
service.datafairs = data.data.rows;
...
});
}...
and from your controller inject the $state service and send to the method the value of $state.current.name
Another way it is inject the $state service directly on your service, like this:
.factory('SearchService', ['$http','$filter','$state', function($http, $filter, $state){
var service = {
getAllExhibitors : function () {
var searchindex = 'Berliner';
var url = '...';
var config = {
params: {
search: searchindex
},
cache:true
};
if($state.current.name === 'berliner') {
config.params.search = 'asdf'
}
....
$http.get(url, config).then(function (data) {
service.datafairs = data.data.rows;
...
});
}...
When working with asynchronous APIs such $http, it is best to return promises:
app.service('SearchService', function($http, $filter) {
this.getAllExhibitors = function (searchArg) {
var searchindex = searchArg || 'Berliner';
var url = '...';
var config = {
params: {
search: searchindex
},
cache:true
};
//RETURN promise
͟r͟e͟t͟u͟r͟n͟ $http.get(url, config).then(function (response) {
͟r͟e͟t͟u͟r͟n͟ response.data.rows;
});
};
});
Then in the controller, extract data from the promise:
app.controller("viewController", function($scope, SearchService, $state) {
var searchArg = $state.current.name;
var promise = SearchService.getAllExhibitors(searchArg);
promise.then(function(rows) {
$scope.rows = rows;
});
});
Also notice the the getAllExhibitors function has been modified to accept a search argument.
The return statement is a very useful thing that isn't used enough.

Pass value from provider to controller in angularJs

I'm trying get data from db to UI. Url given via provider is getting the data.
Controller in controller DetailsProvider.getDashboardDetails() is getting null.
var appmod = angular.module('project.DetailDashboardController', []);
appmod.controller("DetailDashboardController", ['$rootScope', '$scope', '$state', 'DetailsProvider',function($rootScope, $scope, $state,DetailsProvider) {
console.log("DetailDashboardController --- ");
$scope.DetList= DetailsProvider.getDashboardDetails()
}]);
})(window, window.angular);
provider which will call the list
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
Thanks in advance for any kind of reply!
You should return promise from your service method and do thenable in your controller.
Root Cause : your are returning the newData which will initalized later after completing the ajax call.Before completing it,you are returning the same variable which will be always null.
In provider,
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
and in controller,
$scope.list = function() {
DetailsService.getDashboardDetails(function(data){
varr holdIt = data.data.DList;
});
};

how to share login data among controllers?

I have a MainController and a ChatController. The users login with username, passwod and jobname, which are controllered by MainController, but in ChatController, I still need parameter jobname, wondering how to pass it to ChatController?
I wrote methods 'saveJobname' and 'getJobname' in service Auth, but getJobname works well but saveJobname doesn't which could be seen via the console.log(..) statement in ChatController.
Here are some relevant codes:
// ---------------------MainController--------------------
app.controller('MainController', ['Auth', '$scope', '$window', '$rootScope', function(Auth, $scope, $rootScope, $window) {
$scope.info = Auth.info;
var vm = this;
vm.loginData = {};
vm.doLogin = function() {
// ...login processing
Auth
.login(vm.loginData.username, vm.loginData.password)
.success(function(data) {
// ...some more code here
if (data.success) { // if login successfully, then save jobname
$scope.info.myjobname = vm.loginData.jobname;
//Auth.saveJobname(vm.loginData.jobname); //does NOT work either
// ...some more codes here
$window.location.href = $window.location.href + '/../job.html';
}
});
};
}]);
// --------------------ChatController----------------------
app.controller('ChatController', ['Auth', ChatController]);
function ChatController(Auth) {
// ...come other codes here;
console.log(Auth.info.myjobname); // it prints 'hello.world!' but not 'vm.loginData.jobname';
// ...come other codes here;
}
// ------------------- AuthService ------------------------
app.factory('Auth', function($http, $q) {
var authFactory = {};
authFactory.info = {
myjobname: 'hello.world!'
};
// get the API from auth.post('/login', function(...){...})
authFactory.login = function(username, password) {
return $http.post('http://localhost:8080/auth/login', {
username: username,
password: password
}).success(function(data) {
//some code here about token processing
return data;
});
};
authFactory.saveJobname = function(jobname) {
authFactory.info.myjobname = jobname;
};
authFactory.getJobname = function() {
return authFactory.info.myjobname;
};
return authFactory;
});
I prefer the solution not using $rootScope, pls advise.
Thanks a lot.
Add one variable inside Auth factory something like authFactory.info = {} in that you can define your username, password & myjobname.
While using them you need to just bind info object inside controller like
$scope.info = Auth.info
And Auth factory would be like this
// AuthService
app.factory('Auth', function($http, $q) {
var authFactory = {};
authFactory.info = {
myjobname: 'hello.world!'
};
// get the API from auth.post('/login', function(...){...})
authFactory.login = function(username, password) {
return $http.post('http://localhost:8080/auth/login', {
username: username,
password: password
}).success(function(data) {
//some code here about token processing
return data;
});
};
authFactory.saveJobname = function(jobname) {
authFactory.info.myjobname = jobname;
};
authFactory.getJobname = function(){
return authFactory.info.myjobname;
};
return authFactory;
});

How to retrieve data via asynchronous call

I am trying to use promise and service to set the data from http request.
I have something like this
angular.module('myApp').controller('productController', ['$scope', 'testService',
function($scope, testService) {
testService.getProducts().then(function(products){
console.log(products);
})
//getFirstProduct is trigger by ng-click user action.
$scope.getFirstProduct = function(){
var t = testService.getFirstProduct();
console.log(t);
}
}
]);
angular.module('myApp').service('testService', ['Product', '$q',
function(Product, $q) {
var products, firstProduct;
var getFirstProduct = function(){
return firstProduct;
}
var setFirstProduct = function(product) {
firstProduct = product;
}
var getProducts = function() {
var deferred = $q.defer();
//Product is a $resource object to send an http request
Product.query({
id: 123
}, function(result) {
setFirstProduct(result.first);
deferred.resolve(classes);
});
return deferred.promise;
}
return {
setFirstProduct: setFirstProduct,
getProducts: getProducts,
getFirstProduct: getFirstProduct
};
}
]);
I need to be able to get First product but I am not sure how to fix this. Can anyone help me about it? Thanks a lot
I see a number of errors in the code such as missing semicolons, mistyped variable/function names, and that setProducts was clobbering its variable.
Also, added $q, as mentioned by #manube
The following should work better:
angular.module('myApp').controller('productController', ['$scope', 'testService',
function($scope, testService) {
testService.getProducts().then(function(products){
console.log(products);
})
//getFirstProduct is trigger by ng-click user action.
$scope.getFirstProduct = function(){
var t = testService.getFirstProduct();
console.log(t);
}
}
]);
angular.module('myApp').service('testService', ['Product', '$q',
function(Product, $q) {
var products, firstProduct;
var getFirstProduct = function(){
return firstProduct;
}
var setFirstProduct = function(product) {
firstProduct = product;
}
var getProducts = function() {
var deferred = $q.defer();
//Product is a $resource object to send an http request
Product.query({
id: 123
}, function(result) {
setFirstProduct(result.first);
deferred.resolve(classes);
});
return deferred.promise;
}
return {
setFirstProduct: setFirstProduct,
getProducts: getProducts,
getFirstProduct: getFirstProduct
};
}
]);

Controller not firing in AngularJS

I'm having an odd issue in AngularJS where MainCtrl isn't fire at all. I go to localhost/ and it redirects to localhost/#/ but the page is blank. There are no errors/messages in console. I can confirm that /views/main.html is publicly accessible. I don't know why this isn't working. Am I missing anything?
angular.module('TurkApp', ['ngCookies']).config([
'$routeProvider',
function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/views/main.html',
controller: 'MainCtrl'
}).otherwise({ redirectTo: '/' });
}
]);
angular.module('TurkApp', []).controller('MainCtrl', [
'$scope',
'$http',
'$location',
'$cookies',
function ($scope, $http, $location, $cookies) {
$scope.questionIsLoading = true;
$scope.answerButtonsDisabled = true;
$scope.showHelp = false;
$scope.currentRetries = 0;
$scope.acceptedHit;
$scope.currentQuestionText = null;
$scope.currentQuestionID = null;
var AssignmentID, Interest;
var getInterest = function () {
return $cookies.interest;
};
var getAssignmentID = function () {
var qsRegex = new RegExp('(?:\\?|&)AssignmentID=(.*?)(?=&|$)', 'gi'), m, assignmentID = false;
while ((match = qsRegex.exec(document.location.search)) != null) {
assignmentID = match[1];
}
if (!assignmentID) {
assignmentID = $location.search()['AssignmentID'];
}
$scope.acceptedHit = assignmentID == 'ASSIGNMENT_ID_NOT_AVAILABLE' || !assignmentID ? false : true;
return assignmentID;
};
$scope.loadNextQuestion = function () {
$scope.questionIsLoading = $scope.answerButtonsDisabled = true;
$http.get('/workers/' + Interest + '/next-question').success(function (data, status) {
$scope.currentQuestionText = data.text;
$scope.currentQuestionID = data.id;
$scope.questionIsLoading = $scope.answerButtonsDisabled = false;
}).error(function () {
console.log('Answer send failed');
});
};
$scope.sendAnswer = function (answer) {
if (!$scope.questionIsLoading && !$scope.answerButtonsDisabled) {
$scope.questionIsLoading = $scope.answerButtonsDisabled = true;
$http.post('/workers/' + Interest + '/answer-question', {
question_id: $scope.currentQuestionID,
question_text: $scope.currentQuestionText,
answer: answer
}).success(function (data, status) {
$scope.loadNextQuestion();
}).error(function () {
console.log('Answer send failed');
});
}
};
$scope.toggleHelp = function () {
$scope.showHelp = $scope.showHelp ? false : true;
};
var init = function () {
AssignmentID = getAssignmentID();
Interest = getInterest();
$scope.loadNextQuestion();
};
init();
}
]);
You are creating the module 'TurkApp' twice, thereby losing the configuration registered with the first module:
angular.module('TurkApp', ['ngCookies'])
When you include the second parameter to the angular.module function, it creates the module. If you omit the second parameter, it assumes the modules exists and "extends" it.
Change:
angular.module('TurkApp', [])
to:
angular.module('TurkApp')
See the usage section here - http://docs.angularjs.org/api/angular.module

Categories