I'm trying to use $cachefactory in my angular project.
I've created a cache service:
services.js
var AppServices = angular.module('Test.services', [])
.factory('testCache', function($cachefactory){
return $cachefactory('test');
});
and I'm trying to inject it in my controller like this:
TestController.js
var TestController =function($scope, $http, testCache) {
var cache = testCache.get('test');
if(cache) {
$scope.test = cache;
}
else {
var value = "Test Value";
$scope.test = value;
cache.put('test', value);
}
};
However when I run the application and try to retrieve data I get:
Error: [$injector:unpr] http://errors.angularjs.org/1.2.17/$injector/unpr?p0=%24cachefactoryProvider%20%3C-%20%24cachefactory%20%3C-%20testCache
u/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:6:443
ec/l.$injector<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:36:139
c#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:34:195
ec/p.$injector<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:36:209
c#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:34:195
d#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:34:409
ec/p.$injector<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:36:222
c#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:34:195
d#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:34:409
f/<.instantiate#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:35:101
Od/this.$get</<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:66:463
$ViewDirectiveFill/<.compile/<#https://rawgit.com/angular-ui/ui-router/0.2.10/release/angular-ui-router.js:2797:1
N#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:54:85
g#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:47:55
v/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:46:253
updateView#https://rawgit.com/angular-ui/ui-router/0.2.10/release/angular-ui-router.js:2733:1
$ViewDirective/directive.compile/</<#https://rawgit.com/angular-ui/ui-router/0.2.10/release/angular-ui-router.js:2697:11
Yd/this.$get</h.prototype.$broadcast#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:113:355
transitionTo/$state.transition<#https://rawgit.com/angular-ui/ui-router/0.2.10/release/angular-ui-router.js:2114:11
ze/e/l.promise.then/D#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:99:243
ze/f/<.then/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:100:407
Yd/this.$get</h.prototype.$eval#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:111:110
Yd/this.$get</h.prototype.$digest#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:108:180
Yd/this.$get</h.prototype.$apply#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:111:449
e/h<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:122:1
e#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:37:438
se/h.defer/c<#https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:41:120
<div class="ng-scope" ui-view="">
I've read the error page which claims that I've missed defining a dependency. I'm not sure where I missed it though since app.js injects services module so $cachefactory should be visible, right?
Link to example on plunker
There is a typo. Use $cacheFactory instead of $cachefactory
Related
I don't get what I'm doing wrong, I am trying to globally store and pass data from one controller to another via a service. I stored the data in one controller and confirmed that it was stored at the beginning of my buildReportController. Then, when I click a button on my UI, it opens reportResultsController. However, issue is, I can store the data correctly in buildReportController via locationHistoryService.store() but when I go to reportResultsController and calllocationHistoryService.get(), thepreviousLocationvariable inlocationHistoryService` is empty as if the data was never set. Any ideas on how why or how I can "globally" store data and pass it between controllers? Below is my attempt. Thanks!
In reportView.js
angular.module('reportView', [])
.service('locationHistoryService', function(){
var previousLocation = "";
return {
store: function(location){
previousLocation = location;
},
get: function(){
return previousLocation;
}
};
});
In buildReport.js
angular.module('buildReport', ['reportView'])
.controller('buildReportController', ['$rootScope', 'locationHistoryService'], function($rootScope, locationHistoryService){
$rootScope.$on('$locationChangeSuccess', function(e, newLocation, oldLocation){
locationHistoryService.store(oldLocation);
console.log("Old location: ", oldLocation);
});
}
In reportResults.js
angular.module('reportResults', ['reportView'])
.controller('reportResultsController', ['$rootScope', 'locationHistoryService'], function($rootScope, locationHistoryService){
console.log("location : ", locationHistoryService.get());
}
The locationHistoryService.get() method in reportResults.js is called before it is set in buildReport.js.
It would be better if you announce when the previousLocation variable has been set.
In reportView.js
angular.module('reportView', [])
.service('locationHistoryService',['$rootScope'] ,function($rootScope){
var previousLocation = "";
return {
store: function(location){
previousLocation = location;
$rootScope.$broadcast('previous-location-set');
},
get: function(){
return previousLocation;
}
};
});
In reportResults.js
angular.module('reportResults', ['reportView'])
.controller('reportResultsController', ['$rootScope', 'locationHistoryService'], function($rootScope, locationHistoryService){
$rootScope.$on('previous-location-set', function(){
console.log("location : ", locationHistoryService.get());
});
}
Your webapp should have only one module which is automatically bootstrapped by angular, and other modules as dependencies. The syntax of writing service is incorrect. You wrote .service but returning object which .factory should return. Here is working example of your code http://codepen.io/Chyngyz/pen/NxbdpW?editors=101
Also you wrote the safe for minification syntax of controllers incorrect, the function block of controller should be the last item in the array.
I am trying to create a user profile page. Where User can display and edit their information.
This is my Controller.js
var userProfileControllers = angular.module("userProfileControllers", []);
userProfileControllers.controller ('userProfileCtrl', ['$scope', '$location', 'localCache', 'customersignup', function ($scope, $location, localCache, customersignup){
var submitProfile = function() {
//Bind Scope
//
var bindScope = function () {
$scope.userProfile = customersignup.userProfile;
};
var asyncBindScope = function() {
$scope.$evalAsync(bindScope());
};
bindScope ();
}}]);
This is my service.js
var userProfileServices = angular.module("userProfileServices", []);
userProfileServices.factory("customersignup", function() {
return {
userProfile: {fname: "kunal"},
updateProfile: function() {
var userProfile = this.userProfile;
},
}
});
In the HTML, let's say in case of first name I have included ng-model="userProfile.fname" in the input of First Name field. Now, when I am loading the html page, I am getting this error :-
https://docs.angularjs.org/error/$injector/unpr?p0=localCacheProvider%20%3C-%20localCache%20%3C-%20userProfileCtrl
Please check the above link, it is from AngularJS official site.
check you have two modules one is for service and other one is for controller, and note that there is no glue between these two modules, to work this you need to glue these two modules, to do that, import the service module in to controller module as below.
var userProfileControllers = angular.module("userProfileControllers", ['userProfileServices']);
then module userProfileControllers have access to module userProfileServices which service is defined. Other vice you don't have access to service module userProfileServices.
You have to add factory name in controller userProfileServices
I know that there are similar questions here, but I've tried them all without success.
I have a factory, that fetches texts for my application:
__resolveAngularModules__('checkoutWeb.interconnections', ['ngCookies', 'angular-hal', 'LocalStorageModule'])
.factory('msgData', ['$http', 'msgMock', '$location', function ($http, msgMock, $location) {
var url;
switch ($location.host()) {
case 'localhost':
url = '/texts/commerce?version=1';
break;
case 'www2-dev.xxx.com':
url = '/texts/commerce?version=2';
break;
}
return $http.get(url, {
headers: {
'ClientId': 'some-id'
}
}).then(function (response) {
return response;
}, function (response) {
Raven.captureException(new Error("Failed to load texts with status: " + response.status + " " + response.statusText));
return msgMock;
});
}]);
So, if I use directly '/blahblah' in $http.get(), tests are ok, but if I'm trying to use logic described above, I'm getting errors in tests.
I've tried to inject $location and use spyOn($location.prototype, "host").andReturn("localhost"); in beforeEach() block, or use $browser.url, but both didn't work for me.
What am I missing? I'm stuck wit this... Will appreciate any help..
UPDATE:
Just tried solution from here. This example is very similar to mine, but solution still doesn't work. What am I doing wrong? Thanks for help in advance.
So my test looks like this now:
describe('directive: accordionDir', function() {
var accordionDir, element, scope, $location, $rootScope;
beforeEach(module('checkoutWeb'));
beforeEach(inject(function(_$rootScope_, $compile, $httpBackend, _msgMock_, _$location_) {
$rootScope =_$rootScope_;
scope = $rootScope;
$location = _$location_;
spyOn($location, 'host').andReturn('localhost');
scope.msgData = _msgMock_;
$httpBackend.when('GET', '/api/open/texts/commerce?version=1').respond(scope.fmsData);
element ='<div accordion-dir><div class="details"></div><div class="answer" style="display: none;"></div></div>';
element = $compile(element)(scope);
scope.$digest();
}));
it('should call $location host: ', function () {
inject(function(accordionDir){
expect($location.host()).toHaveBeenCalled();
});
});
});
Erros stack:
PhantomJS 1.9.8 (Windows 7 0.0.0) directive: accordionDir should call
$location host: FAILED TypeError: 'undefined' is not an object
(evaluating 'parsed.protocol')
at urlIsSameOrigin (c:/source/checkout-web/bower_components/angular/angular.js:14560)
at sendReq (c:/source/checkout-web/bower_components/angular/angular.js:8419)
at c:/source/checkout-web/bower_components/angular/angular.js:8146
at c:/source/checkout-web/bower_components/angular/angular.js:11682
at c:/source/checkout-web/bower_components/angular/angular.js:11682
at c:/source/checkout-web/bower_components/angular/angular.js:11768
at c:/source/checkout-web/bower_components/angular/angular.js:12811
at c:/source/checkout-web/bower_components/angular/angular.js:12623
at c:/source/checkout-web/src/app/additional-directives/accordion-directve_test.js:18
at invoke (c:/source/checkout-web/bower_components/angular/angular.js:3965)
at workFn (c:/source/checkout-web/bower_components/angular-mocks/angular-mocks.js:2177)
undefined Error: [$injector:unpr] Unknown provider:
accordionDirProvider <- accordionDir
http://errors.angularjs.org/1.2.28/$injector/unpr?p0=accordionDirProvider%20%3C-%20accordionDir
at c:/source/checkout-web/bower_components/angular/angular.js:3801
at getService (c:/source/checkout-web/bower_components/angular/angular.js:3929)
at c:/source/checkout-web/bower_components/angular/angular.js:3806
at getService (c:/source/checkout-web/bower_components/angular/angular.js:3929)
at invoke (c:/source/checkout-web/bower_components/angular/angular.js:3956)
at workFn (c:/source/checkout-web/bower_components/angular-mocks/angular-mocks.js:2177)
at c:/source/checkout-web/bower_components/angular-mocks/angular-mocks.js:2163
at c:/source/checkout-web/src/app/additional-directives/accordion-directve_test.js:25
undefined
Didn't manage to solve this problem with $location use. So my solution to get working tests here was to use window.location.hostname instead of $location in msgData factory. With window.location.hostname you don't need extra code in tests. Cheers!
I have main angular module which knows about server url and I set it like this:
angular.module('main', ["editor"]).constant("main.serverUrl", "http://serverurlhere.com")
I also have editor module on which main module depends. Editor module knows controller name (editor) on server it talks to, but doesn't know the serverUrl, so I want to use the serverUrl constant inside editor module to define editor.serverUrl constant something like this:
angular.module('editor').constant("editor.serverUrl", main.serverUrl + "/editor")
How can I do that?
UPDATE:
var m = angular.module("main", ["editor", "mainModuleProviders"]);
var mProviders = angular.module("mainModuleProviders", []);
mProviders.constant("serverUrl", "http://someserverurl.com");
var e = angular.module("editor", ["mainModuleProviders"]);
e.config(["serverUrl", "$provide", function(serverUrl, $provide){
$provide.value("editor.serverUrl", serverUrl + "/editor/")
}]);
You can try something like this
var e = angular.module("editor", [])
.constant("editor.url", "/editor");
var m = angular.module("main", ["editor"]);
m.constant("serverUrl", "http://someserverurl.com");
m.config(["editor.url","serverUrl", "$provide", function(eu,se,$provide){
$provide.constant("editor.serverUrl",se+eu);
}]);
var e = angular.module("editor", [])
.constant("editor.url", "/editor");
var m = angular.module("main", ["editor"]);
m.constant("serverUrl", "http://someserverurl.com");
m.config(["editor.url", "serverUrl", "$provide",
function(eu, se, $provide) {
$provide.constant("editor.serverUrl", se + eu);
}
]);
e.controller('ctrl', ["$scope", "serverUrl", "editor.url", "editor.serverUrl",
function($scope, su, eu, seu) {
$scope.serverUrl = su;
$scope.editorUrl = eu;
$scope.editorServerUrl = seu;
}
])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="main" ng-controller="ctrl">
<div>serverUrl = {{serverUrl}}</div>
<div>editorUrl = {{editorUrl}}</div>
<div>editorServerUrl = {{editorServerUrl}}</div>
</div>
UPDATE
In AngularJS used dependency injection, so when you add dependency in your module it must be loaded before this module run.
In your first variant: you try use main module that depend on editor module inside editor modue.
For solving you can use third module from your second variant mainModuleProviders, or configure all inside main module.
NOTE: inside angular does not have module, so no matter where declared this constant
var login_app = angular.module('login_app',[]);
login_app.factory('login_service', function($http) {
return {
login: function() {
//return the promise directly.
return $http.get('/service/login')
.then(function(result) {
//resolve the promise as the data
return result.data;
});
}
}
});
login_app.controller('login_controller',
['$scope',
function($scope,login_service){
$scope.login_username = "";
$scope.login_password = "";
$scope.remember_login = false;
$scope.login_button_action = function(){
login_service.login();
}
}]);
I have a login form which is under the scope of this controller and works fine.
whenever I press the login button, login_button_action is getting called via ng-click directive.
my problem is that I keep getting this error in my JavaScript console.
ReferenceError: login_service is not defined
Is there something wrong with the wya my controller is using the service ?
You need to add the login_service to the definitions above:
login_app.controller('login_controller', ['$scope','login_service',
function($scope,login_service){
// Your code using the service.
}]);
And of course...the service script file needs to be linked in the document.
To be complete...you do not have to do this at all if you are not considering minification or such. In that case it can just be
login_app.controller('login_controller', function($scope, login_service){
// Your code using the service.
}]);