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";
})
Related
I have a link that I want to use to pass data to another page. I am able to access the service on the page I go to, but the data is empty.
The HTML:
Female
The service:
var app = angular.module('boxHome', []);
app.controller('boxHomeController', function ($scope, SubscriptionService) {
$scope.saveSubscriptionData = function() {
SubscriptionService.gender = 'male';
SubscriptionService.subscription = 'infant';
console.log(SubscriptionService);
}
});
app.factory('SubscriptionService', function () {
return {
gender: '',
subscription: ''
};
});
The above log statement returns gender: 'male' and subscription: 'infant'.
The page I link to:
var appSignup = angular.module('boxSignup', ['boxHome']);
appSignup.controller('boxSignupController', function ($scope, SubscriptionService) {
$scope.init = function (domainId) {
console.log(SubscriptionService);
};
});
I expect the above log statement to return gender: 'male' and subscription: 'infant'. It returns gender: '' and subscription ''.
Any ideas?
app.service('SubscriptionService',function(){
var gender='';
var subscription='';
this.save=function(gender,subscription){
this.gender=gender;
this.subscription=subscription;
};
this.getGender=function(){
return gender;
};
this.getSubscription=function(){
return subscription;
};
});
.controller('boxHomeController', function ($scope, SubscriptionService) {
$scope.saveSubscriptionData = function() {
SubscriptionService.save('male','infant');
}
});
You are returning new instances of the JSON object with each call to the factory and thus not sharing state. To fix this, declare an object inside the factory that gets returned instead:
app.factory('SubscriptionService', function () {
var service = {};
var info = {};
info.gender = '';
info.subscription = '';
service.getInfo = getInfo;
function getInfo(){
return info;
}
return service;
});
When you use it:
var info = SubscriptionService.getInfo();
console.log(info.subscription);
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
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;
});
How would i change the following code form $http.get to a $resource
//The created resource (not using it for now)
hq.factory('LogsOfUser', function ($resource) {
return $resource('/HQ/Graph/GetLoggedinTimes?userName=:userName', {
userName: '#userName'
})
});
//The Controller
var ModalViewLogActionsCtrl = function ($scope, $http, $log, LogsOfUser, $modal) {
$scope.openLogs = function (userName) {
$http.get("/HQ/Graph/GetLoggedinTimes?userName=" + userName).success(function (data) {
var modalInstance = $modal.open({
templateUrl: 'LogView.html',
controller: 'ModalLogViewInstance',
resolve: {
items: function () {
//$scope.items = data;
$log.log(data);
$scope.items = data;
return $scope.items; //return data;
},
userName: function () {
return userName;
}
}
});
}).error(function () {
alert("eror :(");
});;
};
};
You've already done most of the work. All you need now is to call the service inside the controller :
LogsOfUser.query({
userName: userName
}, function success(data) {
//your code
}, function err() {
alert("Error")
});
Use query to get an array of data, and get to get a single document.
Here is a example how to call a resource from a controller:
app.controller('MainCtrl', function($scope, $resource) {
var userName = 'Bob';
var LoggedinTimes = $resource('/HQ/Graph/GetLoggedinTimes');
var data = LoggedinTimes.get({userName : userName}, function () {
console.log(data);
});
});
First, you would want to move data-related logic behind a Service, so your controller doesn't know about server-specifics. More importantly, your Service becomes reusable as all services in AngularJS are global singletons. your controller stays small, as it should be.
Next, your controller would call getLoggedIntimes() and work with the outcome as if the data is there. The result of a $resource.get() or similar functions return an empty object or array which fills itself when the REST call returns with data.
In your service you would do the actual $resource.get().
something along the lines of the following pseudo code:
//The Controller
var ModalViewLogActionsCtrl = function ($scope, MyService, $log, LogsOfUser, $modal) {
$scope.openLogs = function (userName) {
var items = MyService.getLoggedInTimes(userName);
var modalInstance = $modal.open({
templateUrl: 'LogView.html',
controller: 'ModalLogViewInstance',
resolve: {
items: function () {
$scope.items = items;
return $scope.items;
},
userName: function () {
return userName;
}
}
});
};
};
app.service('MyService', function ($resource) {
var loggedInResource = $resource('/HQ/Graph/GetLoggedinTimes/:userName');
return {
getLoggedInTimes: functio(username) {
return loggedInResource.get({
username: username
});
}
};
});
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;
}
};
}
]);