bob.mazzo
bob.mazzo

Reputation: 5637

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

Upvotes: 0

Views: 59

Answers (2)

runxc1 Bret Ferrier
runxc1 Bret Ferrier

Reputation: 8233

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.

Upvotes: 1

Dave M
Dave M

Reputation: 418

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());
}];

Upvotes: 1

Related Questions