AngularJS : Why is my factory always undefined in my controller? - angularjs

My factory is undefined in my controller and I cannot figure out why. I have created a simple example to illustrate.
Here I create the app:
var ruleApp = angular
.module( "ruleApp", [
"ngRoute",
"ruleApp.NewFactory1",
"ruleApp.NewFactory2",
] );
In this dummy example I'd like to build a factory that does something simple, show an alert box. I'll show two methods of doing this (one works, one does not).
Factory 1:
angular
.module('ruleApp.NewFactory1', [])
.factory('NewFactory1', function() {
return function(msg) {
alert(msg);
};
});
Factory 2:
angular
.module('ruleApp.NewFactory2', [])
.factory('NewFactory2', function() {
var showMessageFunction = function(msg) {
alert(msg);
};
return
{
showMessage: showMessageFunction
};
});
Notice the return type of factory 1 is a function and the return type of factory 2 is an object with a property (which is of type function).
Now look at how I'd like to use both of these factories in my controller:
ruleApp.controller( "RuleController", function( $scope, NewFactory1, NewFactory2 ) {
NewFactory1("1");
NewFactory2.showMessage("2");
});
This is where the problem gets exposed. During execution, I am prompted with the alert box for NewFactory1("1");, but it fails during execution of NewFactory2.showMessage("2"); because NewFactory2 is undefined (TypeError: Cannot call method 'showMessage' of undefined).
Can you help me spot the issue? I want to be able to use factories like NewFactory2 because I want the factories to be able to do more than just one thing (i.e. have more than one single function). By the way, I'm using Angular version 1.2.1.

factory 2 should be (demo)
angular
.module('ruleApp.NewFactory2', [])
.factory('NewFactory2', function() {
var showMessageFunction = function(msg) {
alert(msg);
};
return { // <--------- do not go on a new line after return
showMessage: showMessageFunction
};
});

Related

AngularJS injecting one module in another module and call function

code taken from here http://plnkr.co/edit/jcOwg8HgBGPtod4yCR5j?p=info
i read the below code but still i have confusion that how notifytwo's instance is getting pass to factory notify ?
factory notify has function called sampleFun which call function sampleFunTwo of another factory called notifytwo but i have not found when and how notifytwo's instance is getting pass to factory notify ?
please help me to understand the code flow. thanks
var myModule= angular.module('MyServiceModuleOne', ['MyServiceModuleTwo']);
myModule.controller('TestController', ['$scope', 'notify', function($scope, notify){
$scope.getFn = function() {
notify.sampleFun();
}
}]);
myModule.factory('notify',
function(notifytwo) {
return {
sampleFun: function() {
notifytwo.sampleFunTwo();
},
};
}
);
var myModuleTwo= angular.module('MyServiceModuleTwo',[]);
myModule.factory('notifytwo',
function() {
return {
sampleFunTwo: function() {
alert('From notify two');
}
};
}
);
The notify factory is able to call the factory notifyTwo because notifyTwo is being injected when creating the instance of notify:
myModule.factory('notify',
function(notifytwo) //RIGHT HERE IS WHERE IT'S INJECTED

Issues injecting Angular factories and services

I don't know what it is about injecting factories, but I am having the most difficult time.
I've simulated what I'm attempting to do via this sample plunk http://plnkr.co/edit/I6MJRx?p=preview, which creates a kendo treelist - it works fine.
I have an onChange event in script.js which just writes to the console. That's also working.
My plunk loads the following:
1) Inits the app module, and creates the main controller myCtrl (script.js)
2) Injects widgetLinkingFactory int myCtrl
3) Injects MyService into widgetLinkingFactory
The order in which I load the files in index.html appears to be VERY important.
Again, the above plunk is NOT the real application. It demonstrates how I'm injecting factories and services.
My actual code is giving me grief. I'm having much trouble inject factories/services into other factories.
For example,
when debugging inside function linking() below, I can see neither 'CalculatorService' nor 'MyService' services. However, I can see the 'reportsContext' service.
(function () {
// ******************************
// Factory: 'widgetLinkingFactory'
// ******************************
'use strict';
app.factory('widgetLinkingFactory', ['reportsContext', 'MyService', linking]);
function linking(reportsContext, MyService) {
var service = {
linkCharts: linkCharts
};
return service;
function linkCharts(parId, widgets, parentWidgetData) {
// *** WHEN DEBUGGING HERE, ***
// I CANNOT SEE 'CalculatorService' AND 'MyService'
// HOWEVER I CAN SEE 'reportsContext'
if (parentWidgetData.parentObj === undefined) {
// user clicked on root node of grid/treelist
}
_.each(widgets, function (wid) {
if (wid.dataModelOptions.linkedParentWidget) {
// REFRESH HERE...
}
});
}
}
})();
A snippet of reportsContext'service :
(function () {
'use strict';
var app = angular.module('rage');
app.service('reportsContext', ['$http', reportsContext]);
function reportsContext($http) {
this.encodeRageURL = function (sourceURL) {
var encodedURL = sourceURL.replace(/ /g, "%20");
encodedURL = encodedURL.replace(/</g, "%3C");
encodedURL = encodedURL.replace(/>/g, "%3E");
return encodedURL;
}
// SAVE CHART DATA TO LOCAL CACHE
this.saveChartCategoryAxisToLocalStorage = function (data) {
window.localStorage.setItem("chartCategoryAxis", JSON.stringify(data));
}
}
})();
One other point is that in my main directive code, I can a $broadcast event which calls the WidgetLinking factory :
Notice how I'm passing in the widgetLinkingFactory in scope.$on. Is this a problem ?
// Called from my DataModel factory :
$rootScope.$broadcast('refreshLinkedWidgets', id, widgetLinkingFactory, dataModelOptions);
// Watcher setup in my directive code :
scope.$on('refreshLinkedWidgets', function (event, parentWidgetId, widgetLinkingFactory, dataModelOptions) {
widgetLinkingFactory.linkCharts(parentWidgetId, scope.widgets, dataModelOptions);
});
I am wasting a lot of time with these injections, and it's driving me crazy.
Thanks ahead of time for your assistance.
regards,
Bob
I think you might want to read up on factories/services, but the following will work:
var app = angular.module('rage')
app.factory('hi', [function(){
var service = {};
service.sayHi = function(){return 'hi'}
return service;
}];
app.factory('bye', [function(){
var service = {};
service.sayBye = function(){return 'bye'}
return service;
}];
app.factory('combine', ['hi', 'bye', function(hi, bye){
var service = {};
service.sayHi = hi.sayHi;
service.sayBye = bye.sayBye;
return service;
}];
And in controller...
app.controller('test', ['combine', function(combine){
console.log(combine.sayHi());
console.log(combine.sayBye());
}];
So it would be most helpful if you created a plunk or something where we could fork your code and test a fix. Looking over your services it doen't seem that they are returning anything. I typically set up all of my services using the "factory" method as shown below
var app = angular.module('Bret.ApiM', ['ngRoute', 'angularFileUpload']);
app.factory('Bret.Api', ['$http', function ($http: ng.IHttpService) {
var adminService = new Bret.Api($http);
return adminService;
}]);
As you can see I give it a name and define what services it needs and then I create an object that is my service and return it to be consumed by something else. The above syntax is TypeScript which plays very nice with Angular as that is what the Angular team uses.

angularjs app.service(...) causes "Uncaught TypeError: undefined is not a function"

What worked well in former projects causes an error in the current project.
I have a couple of services for various tasks like this:
angular.module('myApp')
.service('test1', function() {
return {
sayHello : function() {
return ("Hello!");
}
};
})
.service('test2', function() { //this line causes the error
return {
sayHi : function() {
return ("Hi!");
}
};
})
.service('test3', function() {
...
})
When I include this file in my project I get the following error message in the line with the ".service('test2', function()...":
Uncaught TypeError: undefined is not a function
Whatever I am doing - the 2nd method always causes this error. Looks like the first service method does not return an object? Thanks!
It looks like you're missing some closing brackets, so the error that seems to be happening in the second service is actually being caused by a syntax error in the first service.
Try this:
angular.module('myApp')
.service('test1', function() {
return {
sayHello : function() {
return ("Hello!");
}
};
})
.service('test2', function() {
return {
sayHi : function() {
return ("Hi!");
}
};
});
I have now found out what's the problem. I am working on an application which was started by someone else (CLIP-TWO Theme), who defined all services as providers in his router configuration file. That goes like this:
app.service = $provide.service;
When I now define my services the first one will work but the second one won't, because the second one is not in app scope but in provider scope.
So I had to change my service definition like this:
var app = angular.module('myApp'); // this is already done in the main js.
// define all services separately
app.service('test1', function() {...});
app.service('test2', function() {...});
app.service('test3', function() {...});
Try to declare service methods with this.
angular.module('myApp')
.service('test1', function() {
this.sayHello = function() {
return 'Hello';
};
});

Injecting data objects into a directive factory in AngularJS

So I have a directive that takes in data objects as an argument into the scope. The problem is that I handle all my data in my service layer.
So this is some normal non-directive code:
angular.module('app').factory('appFactory', ['appValues', function(appValues) {
var getStuff = function() { return appValues.stuff; };
}]);
But if want to reuse the factory inside a directive and get appValues as an argument:
angular.module('app').directive('myDir', [function() {
return {
...
scope: {
values: '='
}
....
};
}]);
But this puts it on the scope and not into my data layer. So now I need to send the values object to every function call in my directive factory:
angular.module('app').factory('myDirFactory', [function() {
var getStuff = function(values) { return values.stuff; };
}]);
Is there any good pattern to solve this and keep data in the data-layer and bypass the scope/controller?
Also, the factory will be a singleton shared amongst instances of the directive? How should I solve that then? Create a new injector somehow? Submit to putting lots of data object logic into the controller (which I've been thought not to do)?
It was a while ago, and I guess that a simple soultion is simply to provide an function initialize(value) {... return {...};} and then the returned object has access to the value argument without providing it as a parameter everywhere:
angular.module('myDir').factory('myDirFactory', [function() {
var initialize = function(values) {
var getStuff = function() {
return values;
};
return {
getStuff: getstuff;
};
};
return {
initialize: initialize
};
}]);

accessing atributes of a service in angularjs

I created a service to share some data between two controllers. The thing is that this controllers set and get some data from this service. But I don't know why when I try to get data, all this variables are not set.
My code is this one:
var appModule = angular.module('app', ['mgcrea.ngStrap'])
// custom service to share/collect data between controllers
// this objects are populated by the controllers
.service('sharedProperties', function () {
this.searchPattern = {
basicFilters: {},
advanceFilters: {}
};
});
// controller for main section
appModule.controller('parentController', function ($scope, $aside, sharedProperties) {
$scope.basicFilters = {
category: 'undef',
masterbrand: {value:'undef', text: 'Any'},
page: 1,
perPage:10,
q:''
};
// populate object in service
$scope.updatePatternSearch = function(newValue, oldValue, scope) {
sharedProperties.searchPattern.basicFilters = 'HI!, I have a value!';
};
$scope.$watch('basicFilters', 'updatePatternSearch', true);
// get variables from service
$scope.search = function() {
// ** PROBLEM **
// firebug says that is:basicFilters: {},
// advanceFilters: {}
// empties????, why??
console.log(sharedProperties.searchPattern);
}
}
});
There are lots of typos and erros in your plnkr code.
I have forked and updated it. It's working fine.
Have a look at this - http://plnkr.co/edit/BVFjufOQFFlhB2gTqIeB?p=preview

Resources