Pregunta

I am having an issue with injecting the angular toaster service into a factory object I have, when I get toaster injected without errors, the ngAnimate injection fails on the toaster. As far as I can tell I have done it correctly, so I am not sure what I have missed here.

Error Message:

Uncaught Error: [$injector:modulerr] Failed to instantiate module apptSetting due to:
Error: [$injector:modulerr] Failed to instantiate module toaster due to:
Error: [$injector:modulerr] Failed to instantiate module ngAnimate due to:
Error: [$injec...<omitted>...1) 

Main app file:

//Creates the initial angular application module

var app = angular.module("testApp", ['angularSpinner', 'ngResource', 'ui.bootstrap', 'toaster', 'app.controllers', 'app.factories']);
angular.module("app.factories", []);
angular.module("app.controllers", []);

factory file:

angular.module('app.factories').factory('dataFactory', ['$rootScope', '$resource', '$http', 'toaster', function ($rootScope, $resource, $http, toaster) {
return {
    UpdateOrderStatus: function(orderId) {
        return $http({
            url: "/path/UpdateOrderStatus",
            dataType: "json",
            method: "POST",
            data: { orderId: orderId },
            headers: {
                "Content-Type": "application/json; charset=utf-8"
            }
        }).success(function(order) {
            toaster.pop('success', "Order status Update", "Order status successfully updated.");
        }).error(function() {
            //toaster.error("Order status update failed.");
        });
    }

Partial Toaster file:

angular.module('toaster', ['ngAnimate'])
.service('toaster', ['$rootScope', function ($rootScope) {
this.pop = function (type, title, body, timeout, bodyOutputType) {
    this.toast = {
        type: type,
        title: title,
        body: body,
        timeout: timeout,
        bodyOutputType: bodyOutputType
    };
    $rootScope.$broadcast('toaster-newToast');
};

Scripts listing in order:

                    "~/Scripts/angular.js",
                    "~/Scripts/angular-resource.js", 
                    "~/Scripts/ui-bootstrap-tpls-0.10.0.js",
                    "~/Scripts/spin.js",
                    "~/Scritps/angular-animate.min.js",
                    "~/Scripts/toaster.js",
                    "~/Scripts/ApptSettingApp.js",
                    "~/Scripts/angular-spinner.js",
                    "~/Scripts/dataFactory.js",

Update to this issue:

What I have found with this problem, I am using angular in a .net application and my scripts are all rendered using the bundler in my application. Even though the script file reference is the same, and the toaster reference is correct. If you add a tag to the page, sourced to the same script files it will work fine. This however does not resolve the problem, it does give more insight into the cause.

¿Fue útil?

Solución

Well,

The reason behind the issue is simple enough, I was loading a service with the same name more than once... however, the resulting behavior is usual in that if you do not know how angular handles injecting objects with the same name. In my case I was loading the toaster module in my main app where I create all the modules needed for the application. Then I added the directive to the html page so that toaster could display messages, this caused to load the toaster service again, but without a provider (I assume because it was already loaded in the main application), hence the provider error.

Initially to fix it, I added a script tag to the page, and everything worked fine, but since I wanted this to be a global messaging scenario, having to add a script tag to every page bothered me, so I kept digging.

That is when I noticed that the directive was loading the service again. So it was loading in the main module, and then directive was loading it and finally on the page the script tag was overriding the previous 2 implementations. So fixing properly was a matter not loading it in the main app removing the script tag from the html page and simply adding the directive to the page.

This behavior is the result of the way angular handles injecting objects that have the same name, ultimately the last one to the party wins.

I hope this helps the next person who comes across something like this.

Otros consejos

Add toaster module to app.factories dependencies since toaster and dataFactory are in different modules.

angular.module("app.factories", ['toaster']);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top