Angular UI Router not resolving one service before another - javascript

I am trying to create a tag layout filled with categories, but I am not getting my Authentication because I am trying to resolve that service in my Router.
this is my Router code
(function () {
'use strict';
angular
.module('learningApp')
.config(sslRouter);
// Minification safe dependency Injection
sslRouter.$inject = ['$stateProvider'];
function sslRouter ($stateProvider) {
// SSL Route Definition
$stateProvider.state('ssl', {
parent: 'policy',
url: '/ssl',
data: {
roles: ['USER']
},
views: {
'policyConfig': {
templateUrl: 'components/configuration/service/policy/ssl/ssl.tpl.html',
controller: 'SSL'
}
},
resolve: {
'sslServiceData': function(sslService) {
return sslService.promise;
}
}
});
}
}());
This is my Service
(function() {
'use strict';
angular
.module('learningApp')
.factory('sslService', sslResource);
sslResource.$inject = ['Principal', '$resource', 'BASE_URL', 'exDomainService'];
function sslResource (Principal, $resource, BASE_URL, exDomainService) {
debugger;
var res = $resource(BASE_URL + '/api/companies/' + Principal.company() + '/sconfig/ssl/sslConfiguration', {}, {
query: {
method: 'GET',
isArray: false
},
update: {
method: 'PUT'
}
});
var data = {};
var servicePromise = _initService();
servicePromise.$promise.then(function (d) {
data = d;
if (!data.excludedCategories) {
data.excludedCategories = [];
}
if (!data.excludedDomains) {
data.excludedDomains = [];
}
exDomainService.tableData = getExcludedDomains();
});
function _initService () {
return res.query();
}
return {
promise: servicePromise,
rest: res
}
}
}());
This is my controller
(function() {
'use strict';
angular
.module('learningApp')
.controller('SSL', SSLController);
SSLController.$inject = ['$scope', 'sslService', 'preDefinedCategoryService', '$timeout', 'exDialog', 'exDomainService'];
function SSLController ($scope, sslService, preDefinedCategoryService, $timeout, exDialog, exDomainService) {
var vm = $scope;
/**
* #desc Flags for different type checks
* Booleans and Categories
*/
vm.flags = {
// By default true
enableInspectSSLTraffic: sslService.getSSlInspectionFlag(),
allowUntrustedCertificates: sslService.getUntrustedCertificatesFlag(),
allowHostnameMismatch: sslService.getHostnameMismatchFlag(),
selectedCategory: undefined,
initializing: true
};
vm.excludedCategories = sslService.getExcludedCategories();
vm.predefinedCategories = preDefinedCategoryService.rest.query();
vm.predefinedCategories.$promise.then(function() {
vm.categories = _processedCategories(vm.predefinedCategories, vm.excludedCategories);
});
}
}());
So basically problem is, I am getting Principal.Identity as undefined, but if I remove resolution from Router, I got identity but then I lose my data coming from service. I want my service to be loaded completely before its Controller, and I want my principal service to be loaded before service.
for Reference, This is my Principal Class
'use strict';
angular.module('learningApp')
.service('Principal',['$q', 'Account', 'localStorageService', function Principal($q, Account, localStorageService) {
var _identity,
_authenticated = false;
return {
isIdentityResolved: function () {
return angular.isDefined(_identity);
},
isAuthenticated: function () {
return _authenticated;
},
isInRole: function (role) {
if (!_authenticated || !_identity || !_identity.roles) {
return false;
}
return _identity.roles.indexOf(role) !== -1;
},
isInAnyRole: function (roles) {
if (!_authenticated || !_identity.roles) {
return false;
}
for (var i = 0; i < roles.length; i++) {
if (this.isInRole(roles[i])) {
return true;
}
}
return false;
},
company: function () {
debugger;
if (_identity) return _identity.companyId;
},
authenticate: function (identity) {
_identity = identity;
_authenticated = identity !== null;
},
identity: function (force) {
var deferred = $q.defer();
if (force === true) {
_identity = undefined;
}
// check and see if we have retrieved the identity data from the server.
// if we have, reuse it by immediately resolving
if (angular.isDefined(_identity)) {
deferred.resolve(_identity);
return deferred.promise;
}
// rather than retrieving from server, use cookie or whatever method
var cookieFound = UTIL.cookie("token");
if (cookieFound) {
var response = JSON.parse(JSON.parse(cookieFound));
var expiredAt = new Date();
expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
response.expires_at = expiredAt.getTime();
localStorageService.set('token', response);
}
// retrieve the identity data from the server, update the identity object, and then resolve.
Account.get().$promise
.then(function (account) {
account.data.roles = ["ADMIN", 'USER'];
account.data.langKey = "en";
_identity = account.data;
_authenticated = true;
deferred.resolve(_identity);
})
.catch(function() {
_identity = null;
_authenticated = false;
deferred.resolve(_identity);
});
return deferred.promise;
}
};
}]);

Related

AngularJS - How to call a service in a module

I have this controller here that calls a service, it works fine, however I needed to call a method that is inside that service in another module. How can I do this?
BaSiderbarService:
(function() {
'use strict';
angular.module('BlurAdmin.theme.components')
.provider('baSidebarService', baSidebarServiceProvider);
/** #ngInject */
function baSidebarServiceProvider() {
var staticMenuItems = [];
this.addStaticItem = function() {
staticMenuItems.push.apply(staticMenuItems, arguments);
};
/** #ngInject */
this.$get = function($state, layoutSizes) {
return new _factory();
function _factory() {
var isMenuCollapsed = shouldMenuBeCollapsed();
this.getMenuItems = function() {
var states = defineMenuItemStates();
var menuItems = states.filter(function(item) {
return item.level == 0;
});
menuItems.forEach(function(item) {
var children = states.filter(function(child) {
return child.level == 1 && child.name.indexOf(item.name) === 0;
});
item.subMenu = children.length ? children : null;
});
return menuItems.concat(staticMenuItems);
};
this.shouldMenuBeCollapsed = shouldMenuBeCollapsed;
this.canSidebarBeHidden = canSidebarBeHidden;
this.setMenuCollapsed = function(isCollapsed) {
isMenuCollapsed = isCollapsed;
};
// I need call this method in another controller
this.getStorage = function(){
console.log(localStorage.user);
}
this.isMenuCollapsed = function() {
return isMenuCollapsed;
};
this.toggleMenuCollapsed = function() {
isMenuCollapsed = !isMenuCollapsed;
};
this.getAllStateRefsRecursive = function(item) {
var result = [];
_iterateSubItems(item);
return result;
function _iterateSubItems(currentItem) {
currentItem.subMenu && currentItem.subMenu.forEach(function(subItem) {
subItem.stateRef && result.push(subItem.stateRef);
_iterateSubItems(subItem);
});
}
};
function defineMenuItemStates() {
return $state.get()
.filter(function(s) {
return s.sidebarMeta;
})
.map(function(s) {
var meta = s.sidebarMeta;
return {
name: s.name,
title: s.title,
level: (s.name.match(/\./g) || []).length,
order: meta.order,
icon: meta.icon,
stateRef: s.name,
};
})
.sort(function(a, b) {
return (a.level - b.level) * 100 + a.order - b.order;
});
}
function shouldMenuBeCollapsed() {
return window.innerWidth <= layoutSizes.resWidthCollapseSidebar;
}
function canSidebarBeHidden() {
return window.innerWidth <= layoutSizes.resWidthHideSidebar;
}
}
};
}
})();
This is the module I need to inject the service and call the method I need DashboardModule:
/**
* #author v.lugovsky
* created on 16.12.2015
*/
(function() {
'use strict';
angular.module('BlurAdmin.pages.dashboard', [])
.config(routeConfig);
/** #ngInject */
function routeConfig($stateProvider) {
// I need call service here
baSidebarService.getStorage()
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: 'app/pages/dashboard/dashboard.html',
title: 'Dashboard',
resolve: {
user: function(baSidebarService){
console.log('DASHBOARD',baSidebarService.getStorage())
}
},
sidebarMeta: {
icon: 'ion-android-home',
order: 0,
},
});
}
})();
Is there any way to do this? I need to get this method so I can make a logic over that value
Inject the service:
/** #ngInject */
function routeConfig($stateProvider, baSidebarService) {
// I need call service here
baSidebarService.getStorage()

Implementing loading using httpInterceptor and AngularJS

i try to make loading icon appears in all website while requests in all components that requires time in loading i write this code but it didn't work !
this is the directive and controller
(function() {
'use strict';
angular
.module('xreview')
.directive('loading', loading);
/** #ngInject */
function loading() {
var directive = {
restrict: 'E',
templateUrl: 'app/components/directives/loading/loading.html',
scope: {
},
controller: loadingController,
controllerAs: 'scope',
bindToController: true
};
return directive;
/** #ngInject */
function loadingController($rootScope , $httpInterceptor ) {
return function ($scope, element, attrs) {
$scope.$on("loader_show", function () {
return element.show();
});
return $scope.$on("loader_hide", function () {
return element.hide();
});
};
}
}
})();
this is the interceptor factory
(function() {
'use strict';
angular
.module('xreview')
.factory('httpInterceptor', httpInterceptor);
/** #ngInject */
function httpInterceptor($q, $rootScope, $log) {
var numLoadings = 0;
return {
request: function (config) {
numLoadings++;
// Show loader
$rootScope.$broadcast("loader_show");
return config || $q.when(config)
},
response: function (response) {
if ((--numLoadings) === 0) {
// Hide loader
$rootScope.$broadcast("loader_hide");
}
return response || $q.when(response);
},
responseError: function (response) {
if (!(--numLoadings)) {
// Hide loader
$rootScope.$broadcast("loader_hide");
}
return $q.reject(response);
}
};
}
})();
and i injected this in config
$httpProvider.interceptors.push('httpInterceptor');
for example this is a service of on component of the components
vm.postAllComment = function(file){
vm.commentig = true;
var modal = {
comment: vm.allCommentText
};
if (file.file_name != 'Post') {
modal.post_file = file.id;
}
userService.one('reviews', id).post('comments', modal).then(function(result){
vm.commentig = false;
vm.allComments.push.apply(vm.allComments, [{
user: result.user,
content: result.comment,
id: result.id
}]);
vm.allCommentText = '';
vm.post.comments_count ++;
}, function(error){
// error post comment
if (error.status == 403)
userService.userUnauthenticatedHandler();
vm.commentig = false;
});
};
this is the html
<div id="loaderDiv" loading>
<img src="./assets/image/spinner.gif" class="ajax-loader"/>
</div>

Angular service return undefined

I have a problem with my service in angular.
My service has the next code:
app.service("Utilidades", ['$http', '$window', function ($http, $window) {
return {
Get: function (urlAbsoluta, parametros, callback) {
var Utilidades = this;
$http
.get(app.UrlBase + urlAbsoluta, parametros)
.then(function (data) {
var Datos = angular.fromJson(data);
Utilidades.GuardarToken(Datos.Token);
callback(Datos);
});
},
ObtenerMenu: function () {
var Utilidades = this;
Utilidades.Get("Administracion/Api/Usuarios/Menu", {}, function (Datos) {
Datos = angular.fromJson(Datos.data);
if (Datos.Error == "") {
return Datos.Resultado;
} else {
return "";
}
});
}
}
}]);
Then, in my controller i have the next code:
app.controller('LoginCtrl', ['$scope', '$http', '$location', 'Utilidades',
function Iniciador($scope, $http, $location, Utilidades) {
var Li = this;
Li.Usuario = "";
Li.Contrasena = "";
Li.Error = "";
Li.MenuItems = [];
Li.Menu = function () {
Li. MenuItems = Utilidades.ObtenerMenu();
}
}]
);
When i run this, Li.MenuItems have undefined value and i don't know why.
Your return statements are in a function inside your ObtenerMenu method so the ObtenerMenu method is not actually returning anything. You need to provide a way to access the resulting value:
Service
app.service("Utilidades", ['$http', '$window', function ($http, $window) {
return {
Get: function (urlAbsoluta, parametros) {
var Utilidades = this;
// v------------ return statement here
return $http
.get(app.UrlBase + urlAbsoluta, parametros)
.then(function (data) {
var Datos = angular.fromJson(data);
Utilidades.GuardarToken(Datos.Token);
// v------------ return statement here
return Datos;
});
},
ObtenerMenu: function () {
var Utilidades = this;
// v------------ return statement here
return Utilidades.Get("Administracion/Api/Usuarios/Menu", {})
.then(function (Datos) {
if (Datos.Error == "") {
return Datos.Resultado;
} else {
return "";
}
});
}
};
}]);
In Controller
Li.Menu = function () {
Utilidades.ObtenerMenu()
.then(function (resultado) {
Li. MenuItems = resultado;
});
}
It's because ObtenerMenu function is asynchronous function. This function doesn't return anything initially (so undefined) and later, after some time when ajax request finishes, this function is already finished its execution stack

Why am I getting "Incorrect injection token!" in this angular application code?

I'm trying to setup a restful API interface via AngularJS with the following code:
'use strict';
(function(angular) {
function ApiAction($resource, ResourceParameters) {
return $resource(ResourceParameters.route,
{ },
{ api_index: {
method: ResourceParameters.method,
isArray: true
}
});
return $resource(ResourceParameters.route,
{ },
{ create: {
method: ResourceParameters.method,
isArray: true
}
}
);
}
function ResourceParameters($scope) {
var factory = {};
factory.method = '';
factory.route = '';
factory.SetMethod = function(method) {
factory.method = method;
}
factory.SetRoute = function(route) {
factory.route = route;
}
return factory;
}
function superheroCtr($scope, ApiAction, ResourceParameters) {
$scope.superheroSubmit = function() {
// ApiAction.create({}, { superhero_name: $scope.superheroName, age: $scope.superheroAge });
angular.forEach($scope.superheroes, function(hero) {
// ApiAction.create({}, { superhero_name: hero.superhero_name, age: hero.age });
});
};
var heroesResources = ResourceParameters($scope).SetRoute('/api/');
var heroes = ApiAction.api_index({}, heroesResources);
$scope.superheroes = [];
heroes.$promise.then(function(data) {
angular.forEach(data, function(item) {
$scope.superheroes.push(item);
});
}, function(data) {
//if error then...
});
$scope.appendSuperheroFields = function() {
var i = $scope.superheroes.length + 1;
$scope.superheroes.push({"id": i, age: "", superhero_name: "" })
}
}
var superheroApp = angular.module('superheroApp', ['ngResource']);
superheroApp.controller('superheroCtr', ['$scope', 'ApiAction', 'ResourceParameters', superheroCtr]);
superheroApp.factory('ResourceParameters', ['$scope', ResourceParameters]);
superheroApp.factory('ApiAction', ['$resource', ResourceParameters, ApiAction]);
})(angular);
Yet, when I run it I get the following error:
Error: [$injector:itkn] Incorrect injection token! Expected service name as string, got function ResourceParameters($scope)
Why is this?
Simply you can not inject $scope OR you can not have access to $scope
inside a factory
Your problem is at this line
superheroApp.factory('ResourceParameters', ['$scope', ResourceParameters]);
You need to replace that line with
superheroApp.factory('ResourceParameters', [ResourceParameters]);
Factory
function ResourceParameters() { //<--removed $scope from here
var factory = {};
factory.method = '';
factory.route = '';
factory.SetMethod = function(method) {
factory.method = method;
}
factory.SetRoute = function(route) {
factory.route = route;
}
return factory;
}
Update
Additionally you should correct the declaration of ApiAction where ResourceParameters should be placed inside ' single qoutes
superheroApp.factory('ApiAction', ['$resource', 'ResourceParameters', ApiAction]);

'book' is defined but never used MEAN stack controller

I'm having problems creating a variable and using it in a MEAN package. I'm basing it off of the "articles" package that comes as an example. Everything I see is the same in the client-side controller, but I'm not sure why I'm catching the error when I try to start my app (with grunt) on the "books" package but not the "articles" package.
I have not implemented all the controllers that articles has yet, that may be an issue?
When I start the app with grunt, I get this error on : 'book' is defined but never used MEAN stack controller
I believe the error is in the controller, but if you need to see other files please let me know.
books.js
//client-side controller
'use strict';
angular.module('mean.books').controller('BooksController', ['$scope', 'Global', 'Books',
function($scope, Global, Books) {
$scope.global = Global;
$scope.package = {
name: 'books'
};
$scope.hasAuthorization = function(book) {
if (!book || !book.user) return false;
return $scope.global.isAdmin || book.user._id === $scope.global.user._id;
};
$scope.create = function(isValid) {
if (isValid) {
var book = new Books({
title: this.title,
author: this.author,
description: this.description,
seller: this.seller
});
/* Not sure if we need this location thing
book.$save(function(response) {
$location.path('books/' + response._id);
});
*/
this.title = '';
this.content = '';
this.description = '';
this.seller = ''; // or this.user implement
} else {
$scope.submitted = true;
}
};
}
]);
articles.js //this is the example that I'm basing it from
'use strict';
angular.module('mean.articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Global', 'Articles',
function($scope, $stateParams, $location, Global, Articles) {
$scope.global = Global;
$scope.hasAuthorization = function(article) {
if (!article || !article.user) return false;
return $scope.global.isAdmin || article.user._id === $scope.global.user._id;
};
$scope.create = function(isValid) {
if (isValid) {
var article = new Articles({
title: this.title,
content: this.content
});
article.$save(function(response) {
$location.path('articles/' + response._id);
});
this.title = '';
this.content = '';
} else {
$scope.submitted = true;
}
};
$scope.remove = function(article) {
if (article) {
article.$remove(function(response) {
for (var i in $scope.articles) {
if ($scope.articles[i] === article) {
$scope.articles.splice(i, 1);
}
}
$location.path('articles');
});
} else {
$scope.article.$remove(function(response) {
$location.path('articles');
});
}
};
$scope.update = function(isValid) {
if (isValid) {
var article = $scope.article;
if (!article.updated) {
article.updated = [];
}
article.updated.push(new Date().getTime());
article.$update(function() {
$location.path('articles/' + article._id);
});
} else {
$scope.submitted = true;
}
};
$scope.find = function() {
Articles.query(function(articles) {
$scope.articles = articles;
});
};
$scope.findOne = function() {
Articles.get({
articleId: $stateParams.articleId
}, function(article) {
$scope.article = article;
});
};
}
]);
In $scope.create function you defined book
var book = new Books({
and never use it. That's reason you get warning. If you want to skip jshint warnings in development use grunt -f or allow unused variables in your grunt configuration (or .jshintrc if you use it)

Categories

Resources