I'm trying to store a response variable in a global service variable. This is my service:
(function() {
angular.module('employeeApp')
.service('constants',constants);
function constants() {
this.url = 'http://domain.dev/api/v1/';
this.role = '',
this.companyid = '',
this.name = ''
}
})();
loginFactory:
factory.login = function(email,password)
{
var vm = this;
vm.companyid = constants.companyid;
data = {"email": email, "password": password};
requestFactory.post(GLOBALS.url + 'login', data)
.then(function (response) {
vm.role = response.data.result.Employee.Role;
vm.companyid = response.data.result.Employee.CompanyId;
factory.setToken(response.data.result.Employee.api_token);
$cookieStore.put('employeeid', response.data.result.Employee.EmployeeId);
$location.path('/home');
}, function () {
console.log('Niet ingelogd!');
});
}
When I try to access companyid in my homecontroller it's empty. What am I doing wrong. Looking for hours right now but can't find a solution!
You need to inject the constants service into your loginFactory.
https://docs.angularjs.org/guide/di
.factory('loginFactory', ['constants', function(constants) {
Also, you're not returning an object in your constants service
Hey you need to inject the your service as a dependency to you factory
angular.module('employeeApp')
.factory('loginFactory', ['constants', function(constants, $scope) {
$scope.login = function(email,password)
{
var vm = this;
vm.companyid = constants.companyid;
data = {"email": email, "password": password};
requestFactory.post(GLOBALS.url + 'login', data)
.then(function (response) {
vm.role = response.data.result.Employee.Role;
vm.companyid = response.data.result.Employee.CompanyId;
factory.setToken(response.data.result.Employee.api_token);
$cookieStore.put('employeeid', response.data.result.Employee.EmployeeId);
$location.path('/home');
}, function () {
console.log('Niet ingelogd!');
});
}
}
This should work unless there are problems in other parts of your app. Notice semi-colons instead of brackets in function constant and square brackets added to module declaration.
(function() {
angular.module('employeeApp', [])
.service('constants',constants);
function constants() {
this.url = 'http://domain.dev/api/v1/';
this.role = '';
this.companyid = '';
this.name = '';
}
})();
See Fiddle
Related
I have created a service to get the details of a user once he logs in so I can feed this to all my angular controllers:
var app = angular.module('myApp', ['ui.calendar', 'ui.bootstrap']);
app.service('authUser', ['$http', function ($http) {
var _currentUser = {};
$http.get("/Home/GetUser", {
cache: false
}).success(function (data) {
_currentUser.userid = data.userId;
_currentUser.role = data.userRole;
_currentUser.departmentid = data.departmentId;
_currentUser.department = data.userDepartment;
});
this.currentUser = _currentUser;
}]);
app.controller('eventController', ['$scope', 'authUser', '$http', 'uiCalendarConfig', '$uibModal', function ($scope, authUser, $http, uiCalendarConfig, $uibModal) {
$scope.currentUser = authUser.currentUser;
When I try to display the output, it looks alright:
<div>
<label>{{currentUser}}</label>
<label>Id: {{currentUser.userid}}, Role: {{currentUser.role}}, Department Id: {{currentUser.departmentid}}, Department Name: {{currentUser.department}}</label>
</div>
This outputs:
{"userid":"29aa607a-d36b-46bb-a3a7-16bead5f4706","role":"Super
Admin","departmentid":1,"department":"MIS"} Id: 29aa607a-d36b-46bb-a3a7-16bead5f4706, Role: Super Admin, Department Id: 1, Department Name: MIS
But when I try to use the properties of currentUser in my code, nothing is being passed. Example:
$http.get("/Home/GetVenues", {
cache: false,
params: {
currentdepartment: $scope.currentUser.departmentid
}
}).success(function (data) {
// ...
})
I tried
$scope.currentdept = $scope.currentUser.departmentid;
Or
$scope.currentdept = authUser.currentUser.departmentid;
But both of these returns nothing ;m;
I'm apologize if I'm missing something really simple here, but I'm a potato please have mercy ;m;
If it is related at all here is my GetUser method from my HomeController:
public JsonResult GetUser()
{
if (Request.IsAuthenticated)
{
ApplicationDbContext db = new ApplicationDbContext();
var user = db.Users.Find(User.Identity.GetUserId());
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(ApplicationDbContext.Create()));
string id = userManager.FindById(User.Identity.GetUserId()).Id;
IList<string> roleNames = userManager.GetRoles(id);
ReservationsDatabaseModel dept = new ReservationsDatabaseModel();
Department department = dept.Departments.Find(user.DepartmentID);
userDepartmentRole user_department_role = new userDepartmentRole();
user_department_role.userId = user.Id;
user_department_role.departmentId = user.DepartmentID;
user_department_role.userDepartment = department.Name;
user_department_role.userRole = roleNames.FirstOrDefault();
return new JsonResult { Data = user_department_role, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
else
{
userDepartmentRole user_department_role = new userDepartmentRole();
user_department_role.userId = "0";
user_department_role.departmentId = 0;
user_department_role.userDepartment = "0";
user_department_role.userRole = "Guest";
return new JsonResult { Data = user_department_role, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
The fetch of /Home/GetVenues needs to wait for the authUser data to arrive from the server.
Change the service to save a promise:
app.service('authUser', ['$http', function ($http) {
var _ = this;
this.currentUser = {};
this.currentUserPromise = $http.get("/Home/GetUser", {
cache: false
}).then(function (response) {
var data = response.data;
_.currentUser.userid = data.userId;
_.currentUser.role = data.userRole;
_.currentUser.departmentid = data.departmentId;
_.currentUser.department = data.userDepartment;
return data;
});
}]);
Then use that promise in the controller:
authUser.currentUserPromise.then(function(userData) {
$http.get("/Home/GetVenues", {
cache: false,
params: {
currentdepartment: userData.departmentid
}
}).then(function (response) {
var data = response.data;
// ...
})
});
This way the controller waits for the authData to arrive from the server before fetching from /Home/GetVenues.
Your call should work only after GetUser API is returned, you can test by putting GetVenues call on a button click rather than running on init.
This is an ASP.NET MVC app with AngularJS.
When the application loads, we have to call some action method which returns a dictionary of resources, string key string value.
This array/dictionary of resources, needs to be available throughout the application.
How can we wait until these resources are loaded before accessing them within the application?
var app = angular.module("app", []);
app.controller("TestCtrl", ['cacheService', function (cacheService) {
var self = this;
self.test = function () {
var value = cacheService.getResourceValue('Err_lbl_UserExist');
}
}]);
app.factory('cacheService', ['$http', function ($http) {
var obj = {};
obj.resourceDictionary = [];
obj.loadResourceDictionary = function () {
var httpConfig = {
url: "/Cache/GetResourceDictionary",
method: "GET",
headers: {
"X-Requested-With": 'XMLHttpRequest',
"__RequestVerificationToken": $("[name=__RequestVerificationToken]").val()
}
}
$http(httpConfig)
.success(function (data) {
obj.resourceDictionary = data;
});
}
obj.getResourceValue = function (resourceKeyName) {
if (obj.resourceDictionary.length <= 0) {
obj.loadResourceDictionary();
}
return obj.resourceDictionary[resourceKeyName];
}
return obj;
}]);
EDIT w/ Accepted Answer
var app = angular.module("app", []);
app.controller("TestCtrl", ['cacheService', function (cacheService) {
var self = this;
self.test = function () {
var value = cacheService.getResourceValue('Err_lbl_UserExist');
}
}]);
app.factory('cacheService', ['$rootScope', '$http', function ($rootScope, $http, $q) {
var obj = { resourcesLoaded: false };
obj.loadResourceDictionary = function () {
obj.resourcesLoaded = false;
var httpConfig = {
url: "Cache/GetResourceDictionary",
method: "GET",
headers: {
"X-Requested-With": 'XMLHttpRequest',
"__RequestVerificationToken": $("[name=__RequestVerificationToken]").val()
}
}
$http(httpConfig).success(function (data) {
obj.resourceDictionary = data;
obj.resourcesLoaded = true;
$rootScope.$broadcast("ResourcesLoaded", null);
});
}
obj.getResourceValue = function (resourceKeyName) {
if (!obj.resourcesLoaded) {
obj.loadResourceDictionary();
$rootScope.$on("ResourcesLoaded", function () {
return obj.resourceDictionary[resourceKeyName];
});
} else {
return obj.resourceDictionary[resourceKeyName];
}
}
return obj;
}]);
you could use broadcast and on for that.
So once your keys are loaded you fire an event using broadcast
https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$broadcast
you listen for that message wherever you need to using on :
https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$on
you can store the data in a service, this will make it a singleton and you can reuse it, all you have to do is inject the service in whatever controller you need.
I'm trying to set a global for my entire app. But it's not working. Here I declare my globals:
(function() {
angular.module('employeeApp')
.controller('authenticationController', authenticationController)
.constant('GLOBALS', {
url:'http://skindustries.dev/api/v1/',
role:'',
companyid:'',
name:''
});
Then when a employee signs in I want to set globals.
function authenticationController(requestFactory,authenticationFactory,GLOBALS,$location,$cookieStore)
{
var vm = this;
vm.login = function() {
data = {"email": vm.email, "password": vm.password};
requestFactory.post(GLOBALS.url + 'login', data)
.then(function (response) {
console.log(response);
GLOBALS.role = response.data.result.Employee.Role;
GLOBALS.companyid = response.data.result.Employee.CompanyId;
authenticationFactory.setToken(response.data.result.Employee.api_token);
$cookieStore.put('employeeid', response.data.result.Employee.EmployeeId);
$location.path('/home');
}, function () {
console.log('Niet ingelogd!');
});
}
}
If I console.log(GLOBALS.role) in authenticationController result is superadministrator. Then the user is redirected to home. If I console.log(GLOBALS.role) in my homeController.
(function()
{
angular.module('employeeApp').controller('homeController', homeController);
function homeController(employeeFactory,GLOBALS) {
console.log(GLOBALS.role);
Result is null?
What am I doing wrong here!?
--EDIT--
constant (service)
(function() {
angular.module('employeeApp')
.service('constants',constants);
function constants() {
this.url = 'http://skindustries.dev/api/v1/';
this.role = 'oldRole',
this.companyid = '',
this.name = ''
}
})();
login (factory)
factory.login = function(email,password)
{
console.log('login');
data = {"email": email, "password": password};
requestFactory.post(GLOBALS.url + 'login', data)
.then(function (response) {
constants.role = response.data.result.Employee.Role;
constants.companyid = response.data.result.Employee.CompanyId;
factory.setToken(response.data.result.Employee.api_token);
$cookieStore.put('employeeid', response.data.result.Employee.EmployeeId);
$location.path('/home');
}, function () {
console.log('Niet ingelogd!');
});
}
homeController
(function()
{
angular.module('employeeApp').controller('homeController', homeController);
function homeController(constants) {
console.log(constants.role);
}
Basically value (or a constant) initializes every time when it is injected in a controller. So it never retain your new value and hence initializes its old value.
For your need you could use a service as a global object in your application so that it retains your new saved value in the GLOBAL object
Demo Fiddle
.service('GLOBALS', function() {
this.url = 'http://skindustries.dev/api/v1/';
this.role = 'oldRole',
this.companyid = '',
this.name = ''
})
.controller('MyController', function(GLOBALS, $scope) {
console.log(GLOBALS.role);
$scope.role = GLOBALS.role;
GLOBALS.role = "new role";
console.log(GLOBALS.role);
})
.controller('MyController2', function(GLOBALS, $scope) {
console.log(GLOBALS.role);
$scope.role = GLOBALS.role;
});
For a better understanding of constants and values refer this question
Hope this helps.
A constant can not be intercepted by a decorator, that means that the value of a constant should never be changed.
Use Value :
angular.module('app', []);
.value('GLOBALS', 'The Matrix');
.controller('MyController', function (GLOBALS) {
GLOBALS = "hello";
})
Hi I am new to angularjs and any help will be appreciated. I am authorising users with a service and my service looks like this
'use strict';
app.factory('Auth', function ($firebaseSimpleLogin, FIREBASE_URL, $rootScope, $firebase) {
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
register: function (user) {
return auth.$createUser(user.email, user.password);
},
createProfile: function (user) {
var profile = {
userfirstname: user.fname,
userlastname: user.lname,
username: user.fname + " " + user.lname,
userprofiletags: user.profiletags
};
var profileRef = $firebase(ref.child('profile'));
return profileRef.$set(user.uid, profile);
},
login: function (user) {
return auth.$login('password', user);
},
logout: function () {
auth.$logout();
},
resolveUser: function () {
return auth.$getCurrentUser();
},
signedIn: function () {
return !!Auth.user.provider;
},
user: {}
};
$rootScope.$on('$firebaseSimpleLogin:login', function (e, user) {
console.log('logged in');
angular.copy(user, Auth.user);
Auth.user.profile = $firebase(ref.child('profile').child(Auth.user.uid)).$asObject();
console.log(Auth.user);
});
$rootScope.$on('$firebaseSimpleLogin:logout', function () {
console.log('logged out');
if (Auth.user && Auth.user.profile) {
Auth.user.profile.$destroy();
}
angular.copy({}, Auth.user);
});
return Auth;
});
I am trying to access the userprofiletags variable from a controller as coded below
'use strict';
app.controller('PostsCtrl', function ($scope, $http, Post, $location, Auth) {
$scope.user = Auth.user;
$scope.signedIn = Auth.signedIn;
$scope.logout = Auth.logout;
$scope.usertags = $scope.user.profile.userprofiletags;
console.log($scope.usertags);
$scope.loadTags = function (query) {
return $http.get('support/tags.json');
};
$scope.onChange = function (cbState) {
$scope.message = "The switch is now: " + cbState;
};
$scope.posts = Post.all;
$scope.post = {
title: '',
description: '',
tags: [],
Anonymous: 'false'
};
var createdtime = moment().format('MMMM Do YY, h:mm:ss a');
$scope.submitQuestion = function () {
$scope.post.createdTime = createdtime;
$scope.post.creator = $scope.user.profile.username;
$scope.post.creatorUID = $scope.user.uid;
Post.create($scope.post).then(function (ref) {
$location.path('/posts/' + ref.name());
});
};
$scope.deletePost = function (post) {
Post.delete(post);
};
});
When I try to access the variable from the view using {{user.profile.userprofiletags}} it gives me the values. but I am getting undefined as the result when I try to assign the variable to $scope.usertags in my PostsCtrl.
I would apologise if I was not clear enough. Please do help me this error. Your help is much appreciated.
I think that the problem here is with console.log very short after making a call so basically $scope.user.profile.userprofiletags doesn't exist at this point in time, in fact it will be ready when this event is broadcasted '$firebaseSimpleLogin:login'
you can either use $watch and destroy it after receiving data
watchDestroyer = $scope.$watch('user.profile', function (newUserProfile) {
if (typeof newUserProfile !== "undefined" && newUserProfile !== null) {
$scope.user = newUserProfile
watchDestroyer()
}
})
or utilise the event or use promises
As Firebase calls are asynchronous, Auth.user is undefined at this point of time. You could do something like this in your controller:
Auth.resolveUser().then(function(user) {
$scope.usertags = user.profile.userprofiletags;
});
There is a service I use to get data from firebase:
'use strict';
angular.module('flbi.services.trainings', [])
.factory('trainingsService', ['FBURL',
function(FBURL) {
return {
getList: function() {
var queryLimit = 10;
var firebase = new Firebase(FBURL);
firebase.child('trainings').limit(queryLimit).on('value', function(trainings) {
var allTrainings = trainings.val();
$.each(allTrainings, function(training) {
firebase.child('users/' + allTrainings[training].userid).on('value', function(user) {
allTrainings[training].user = user.val();
allTrainings[training].user.gravatar = MD5(allTrainings[training].user.email);
});
});
});
}
};
}]);
The function getList() is called from:
$routeProvider
.when('/', {
controller: 'trainingsCtrl',
templateUrl: 'views/default.html',
resolve: {
"trainings": function(trainingsService) {
return trainingsService.getList();
}
}
})
And the controller:
'use strict';
angular.module('flbi.controllers.trainings', ['flbi.services.trainings'])
.controller('trainingsCtrl', ['$scope', 'trainings',
function($scope, trainings) {
console.log(trainings); <-- just empty ....
$scope.trainings = trainings;
}]);
How can I return the data of allTrainings to my controller? I always get an empty Object. But if I check console.log(allTrainings) inner the on()-method of the service, it is full of data...
You resolve method must return a promise in order for this to work as expected. So your getList method should return a promise.
Also, prefer snapshot.forEach() to using .val() as this is highly optimized (it iterates the pointers rather than parsing and collecting all the data into an object and it also sorts the records to match the data, since JavaScript objects are inherently unordered).
angular.module('flbi.services.trainings', [])
.factory('trainingsService', ['FBURL', '$q',
function(FBURL, $q) {
return {
getList: function() {
var def = $q.defer();
var queryLimit = 10;
var firebase = new Firebase(FBURL);
firebase.child('trainings').limit(queryLimit).on('value', function(trainings) {
var promises = [];
var allTrainings = {};
trainings.forEach(function(ss) {
var key = ss.name();
var d = $q.defer();
promises.push(d.promise);
// put any other data you need in the trainings keys here
// allTrainings[key].widget = ss.child('widget').val();
firebase.child('users/' + allTrainings[key].userid).on('value', function(user) {
allTrainings[key].user = user.val();
var email = user.child('email').val();
allTrainings[key].user.gravatar = MD5(email);
d.resolve();
}, d.reject);
$q.when(promises).then(function() {
def.resolve(allTrainings);
}, def.reject);
});
}, def.reject);
return def.promise;
}
};
}
]);