简体   繁体   中英

Error: [ng:areq] Argument 'fn' is not a function, got Object

Versions:

  • angular v1.6.4
  • ui-router v0.3.2

I am in the process of converting a large angular application to be built using webpack. Since I setup the build process I'm getting this error repeated multiple times in my Chrome developer console.

Error: [ng:areq] Argument 'fn' is not a function, got Object

I have found that when I comment out the entire resolve section (where ui route states are being setup) from the code block below I get no errors but my application views don't fire off and hence my app does not work. For context this code is inside a function which is added as a config block to the main angular application module.

$stateProvider.state('productCart', {
    url: '/productCart',
    resolve: {
        initProductCartService: [
            '$state', '$q', 'constants', 'ProductCartService', 'ConfigService', 'StateService',
            function($state, $q, constants, ProductCartService, ConfigService, StateService) {
                var isReadOnlyMode = StateService.isReadOnlyMode;
                var isBypassProductCart = constants.systemProperties.IsBypassShoppingCart;
                var productCartState = constants.systemProperties.productCartState;

                return ProductCartService.getProductCartItems(true).then(function(productCartLineItems) {
                    if(!(angular.isArray(productCartLineItems) && productCartLineItems.length > 0) && !isReadOnlyMode || isBypassProductCart){
                    $state.go('catalog');

                } else {
                    return ConfigService.getProductCartPageUrl().then(function(pageUrl) {
                        if (pageUrl != null) {
                            window.location = pageUrl;
                            //handles first time returning from VF page scenario
                            window.setTimeout(function(){window.location = pageUrl}, 1000);
                            return $q.reject();
                        } else if (productCartState != null && productCartState == 'productcart') {
                            $state.go('productcart');

                        }
                    });
                }
            });
        }
    ]
},
views: {
    'header@': {
        template: require('./views/header-global.html')
    },
    'selector@productCart': {
        template: require('./views/selector-summary.html')
    },
    'cNotification@productCart': {
        template: require('./views/c-notification.html')
    },
    'recommendedProducts@productCart': {
        template: require('./views/recommended-products.html')
    },
    'processIcon@': {
        template: require('./views/process-icon.html')
    },
    'notification@': {
        template: require('./views/notification.html')
    },
    'actions@': {
        template: require('./views/actions.html')
    },
    'layout@': {
        template: require('./views/layout.html')
    },
    'layoutSingle@productCart': {
        template: require('./views/product-cart.html')
    }
},
onEnter: [
    'ConstraintRulesService',
    function (ConstraintRulesService) {
        ConstraintRulesService.setContext(0, [0]);
    }
]
});

I have come across multiple questions regarding similar errors but their issue/solution does not seem to be the same as mine. I have looked into some documentation regarding the stateProvider and it appears I have the resolve section defined correctly as far as I can tell. Please let me know if you need me to provide more pieces of the puzzle just keep in mind this is a large angular app.

NOTE: I did upgrade the version of ui-router to v0.3.2 when converting to webpack since when I attempted to install the older version I using npm I would get the following error.

angular-ui-router@0.2.15 invalid

I added the following event listener for state provider errors.

angular.module('myModule').run( function($rootScope) {
    $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
        debugger
    });
});

I got the following from the toState and fromState arguments. I'm not sure if it provides any clues. I omitted the views' template contents due to large amounts of HTML which takes away from what I'm trying to illustrate. The event argument does not appear to contain anything of value that I can see, toParams is an empty object, fromParams is an empty object and error param simply contains the error I posted in the title of this question.

toState = {
    "url": "/productCart",
    "resolve": {
    "initProductCartService": [
        "$state",
        "$q",
        "constants",
        "ProductCartService",
        "ConfigService",
        "StateService",
        null
    ]
},
    "views": {
    "header@": {
        "template": "HEADER TEMPLATE CONTENT",
            "resolveAs": "$resolve"
    }
},
    "onEnter": [
    "ConstraintRulesService",
    null
],
    "name": "productCart"
}

fromState =     {
    "name": "",
    "url": "^",
    "views": null,
    "abstract": true
}

I downgrade ui-router to 0.2.15 (it installed in spite of the invalid warning/error) and continue to get this error.

This is not directly related to a ui-route issue in my case. While angular was bootstrapping one of my services it was getting an "Object" instead of a function which it was expecting. The part I struggled with was understanding which service was the culprit (this app has hundreds of services making it difficult to just simply go through each service one by one). In order to determine the culprit I switched to the non-minified version of angular then used chrome developer tools "Sources" tab and checked the "Pause On Caught Exceptions" checkbox. At first you may pick up other exceptions unrelated to your app so you may need to F8 a few times (or more) till you see your error in red colored font. Looking at the stack trace on the right hand side I was able to start from the last stack and work my way up the stack till I came across a location in the angular library with a "serviceName" variable that actually indicated the service which it was failing to instantiate. I was also able to locate a "cache" variable in the angular library (an array of instantiated modules) and noticed my service in this array. Looking at other services in the array they were of type function while the faulty service showed as having a type of "Object" (ah ha!). This service was not following the proper service format and therefore angular was unable to instantiate it. While this is completely my fault if it wasn't too much trouble it would be awesome if the angular library would include the name of the failing module in the error message.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM