Angular global factory - angularjs

I created a factory that I would like to use in different pages:
var sessionApp = angular.module('sessionApp', ['LocalStorageModule']);
sessionApp.config(function(localStorageServiceProvider)
{
localStorageServiceProvider
.setPrefix('mystorage')
.setStorageType('localStorage');
});
sessionApp.factory('SessionFactory', function(localStorageService)
{
var service = {};
var _store = 'session';
service.load = function()
{
var session = localStorageService.get(_store);
}
service.save = function(data)
{
localStorageService.set(_store, JSON.stringify(data));
}
service.delete = function()
{
localStorageService.remove(_store);
}
return service;
});
Then I would add it on apps run method where I would assign it to the $rootScope. I left that part of the code commented out for now.
var loginApp = angular.module("loginApp", []);
loginApp.run(function($rootScope, SessionFactory)
{
//$rootScope.sessionFactory = SessionFactory;
$rootScope.$on('$routeChangeStart',
function(ev, next, current)
{
});
});
My error is:
Unknown provider: SessionFactoryProvider <- SessionFactory
Is it because my factory is from sessionApp and my login module is loginApp? Does that mean that I need to have the variables named the same like below:
File: login.js
var myApp = angular.module("loginApp", []);
myApp.run(function($rootScope, SessionFactory)
{
//$rootScope.sessionFactory = SessionFactory;
$rootScope.$on('$routeChangeStart',
function(ev, next, current)
{
});
});
File: session.js
myApp.config(function(localStorageServiceProvider)
{
localStorageServiceProvider
.setPrefix('mystorage')
.setStorageType('localStorage');
});
myApp.factory('SessionFactory', function(localStorageService)
{
var service = {};
var _store = 'session';
service.load = function()
{
var session = localStorageService.get(_store);
}
service.save = function(data)
{
localStorageService.set(_store, JSON.stringify(data));
}
service.delete = function()
{
localStorageService.remove(_store);
}
return service;
});

The array argument to angular.module is an array of other modules that you new module depends on. loginApp needs to list sessionApp as a dependency.
var loginApp = angular.module("loginApp", ["sessionApp"]);

Related

Angular $injector:unpr] Unknown provider:

Working through a test app with a service and I keep getting an error about adding the service using the factory method. Not sure why, i know i am probably staring right at the problem..
The error i get is:
VM497 angular.js:10126 Error: [$injector:unpr] Unknown provider: githubProvider <- github
http://errors.angularjs.org/1.2.28/$injector/unpr?p0=githubProvider%20%3C-%20github
Thanks in advance.
(function() {
var github = function($http) {
var getUser = function(username) {
return $http.get('https://api.github.com/users/' + username).then(function(response) {
return response.data
});
};
var getRepos = function(user) {
return $http.get(user.repos_url).then(function(response) {
return response.data;
});
};
return {
getUser: getUser,
getRepos: getRepos
};
};
var module = angular.module("githubViewer");
module.factory('github', github) ;
});
Controller that injects the service
// Code goes here
(function() {
var app = angular.module("githubviewer", []);
var MainController = function(
$scope, github, $interval,
$log, $anchorScroll, $location) {
var onUserComplete = function(data) {
$scope.user = data;
github.getRepos($scope.user).then(onRepos, onError);
};
var onRepos = function(data){
$scope.repos = data;
$location.hash("userDetails");
$anchorScroll();
}
var onError = function(reason) {
$scope.error = "Could not fetch the Data";
};
var decrementCountDown = function(){
$scope.countdown -= 1;
if($scope.countdown < 1){
$scope.search($scope.username);
}
};
var countDownInterval = null;
var startCountDown = function(){
countDownInterval = $interval(decrementCountDown, 1000, $scope.countdown);
};
$scope.search = function(username){
$log.info("Searching for: " + username);
github.getUser(userName).then(onUserComplete, onError);
if (countDownInterval) {
$interval.cancel(countDownInterval);
}
};
$scope.username = "angular";
$scope.message = "GitHub Viewer";
$scope.repoSortOrder = "-stargazers_count";
$scope.countdown = 5;
startCountDown();
};
app.controller("MainController", MainController)
}());
You need to inject the service into app, from the code you posted. you are not injecting anything into the module.
var app = angular.module("githubviewer", ['yourservice', function(yourservice){}]);
This should get you headed in the right direction.
found my problem, the name of my module had a typo on capitalization. The V in Viewer was wrong.
Controller - var app = angular.module("githubviewer", []);
Service - var module = angular.module("githubViewer");

How to use a service defined in another module than the controller calling it?

I have a module with a service defined:
var ngError = angular.module('ngError', []);
ngError.service('ErrorService', ['$scope', function($scope) {
$scope.displayErrors = function(errors) {
alert(errors);
}
}]);
Then I have another module:
var ngLogin = angular.module('ngLogin', ['ngError']);
Which has a controller that attempts to use the first service defined on ngError:
ngLogin.controller('LoginCtrl', ['$scope', 'LoginService', 'ErrorService', function($scope, LoginService, ErrorService) {
$scope.user = {};
$scope.user.id = 0;
$scope.user.token = '';
$scope.login = function(callback) {
LoginService.login($scope.user.username, $scope.user.password, function(token) {
$scope.setToken(token);
$scope.$apply();
if (typeof callback === 'function') {
callback(callback);
}
}, function(errors) {
ErrorService.displayErrors(errors);
});
};
}]);
But some reason this is throwing the following error:
Unknown provider: $scopeProvider <- $scope <- ErrorService
You cannot use $scope within a service. Change the service as follows and it will work:
var ngError = angular.module('ngError', []);
ngError.service('ErrorService', [function() {
this.displayErrors = function(errors) {
alert(errors);
}
}]);
Try like this , working best for me
var app = angular.module('MyApp', []);
app.service('MyService', function () {
var property = 'First';
this.myFunc = function (x) {
return x*5;
}
});
//
controller 2 under second app module
var app = angular.module('AnotherApp',[]);
app.controller("AnotherAppCtrl", function($scope,MyService) {
$scope.value = MyService.myFunc(4);
});

How to load data from a factory service before using in application

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.

How to refresh Angular $http cache?

My service populates all items using $http and a cache when the controller is activated. If I create a new item, by doing an $http.post(), what is the best way to refresh the cache?
The problem with the example below is the cached getAll call will return an outdated array:
(function () {
'use strict';
angular
.module('myapp')
.factory('items', itemsService)
.controller('Items', itemsController);
// myCache was created using angular-cache
itemsService.$inject = ['$http', 'myCache'];
function itemsService ($http, myCache) {
var service = {
getAll : function () {
return $http.get('/api/item', myCache);
},
createNew : function (item) {
return $http.post('/api/item', item);
}
};
return service;
}
itemsController.$inject = ['items'];
function itemsController (items) {
var vm = this;
vm.items = [];
vm.item = {};
activate();
function activate() {
items.getAll().then(function(response){
vm.items = response.data || [];
});
}
function createNew() {
items.createNew(vm.item).then(function(response){
vm.items.push(response.data);
});
}
}
})();
Edit #1 : Invalidating Cache
I've modified the code to invalidate the cache when a new item is created. The addition of the $q service, and manually rejecting or resolveing the calls seems very tedious and bloated.
Is there a better way?
(function () {
'use strict';
angular
.module('myapp')
.factory('items', itemsService)
.controller('Items', itemsController);
itemsService.$inject = ['$q', '$http', 'CacheFactory'];
function itemsService ($q, $http, CacheFactory) {
var _cache = CacheFactory.get('items') || CacheFactory('items');
var service = {
getItems : function(refresh) {
var d = $q.defer();
if (refresh) { _cache.invalidate(); }
$http.get('/api/item', _cache).then(function(response){
d.resolve(response.data);
}, function(err){ d.reject(err); });
return d.promise;
},
createNew : function(info){
var d = $q.defer();
$http.post('/api/item', info).then(function(response){
_cache.invalidate();
d.resolve(response.data);
}, function(err){ d.reject(err); });
return d.promise;
}
};
return service;
}
itemsController.$inject = ['items'];
function itemsController (items) {
var vm = this;
vm.items = [];
vm.item = {};
activate();
function activate() {
items.getAll().then(function(response){
vm.items = response.data || [];
});
}
function createNew() {
items.createNew(vm.item).then(function(response){
vm.items.push(response.data);
});
}
}
})();

k[$c].maps.Load is not a function

I want to load a map with pins stored in json file in angular app.
but i'm facing with this error!
k[$c].maps.Load is not a function
appControllers.controller('mapController', function($scope, $http) {
$http.get("data/markers.json").success(function(data) {
$scope.offices = data;
$scope.insertGoogleScript();
});
$scope.insertGoogleScript = function() {
var script = document.createElement("script");
script.src = "http://maps.googleapis.com/maps/api/js?callback=loaded";
document.getElementById('mainMap').appendChild(script);
}
$scope.loadMap = function() {
angular.forEach($scope.offices, function(office) {
console.log('#');
});
}
});
function loaded() {
var appElement = document.querySelector('[ng-controller="mapController"]');
var $scope = angular.element(appElement).scope();
$scope.$apply(function() {
$scope.loadMap();
});
}

Resources