web-dev-qa-db-fra.com

L'argument 'fn' n'est pas une fonction ayant une chaîne

J'ai une partie dans mon application angulaire sur laquelle j'ai lié un contrôleur,
depuis lors, j'ai l'argument 'fn' n'est pas une fonction Error, quelqu'un peut-il consulter mon code et expliquer pourquoi j'ai cette erreur?

Je serais très reconnaissant :)

balise HTML:

<section class="col-lg-12" data-ng-controller="MessageController">
  <fieldset>
    <legend>{{ 'MESSAGES' | translate }}</legend>
  </fieldset>
  <div class="margin-left-15">
    <ul class="list-style-button">
      <li data-ng-repeat="message in MSG">{{ message }}</li>
    </ul>
  </div>
</section>

manette:

(function() {
  'use strict';

  var controllers = angular.module('portal.controllers');

  controllers.controller('MessageController', ['$scope', 'MessageService', '$rootScope', function MessageController($scope, MessageService, $rootScope) {
    $rootScope.MSG = MessageService.getMessages();

    $rootScope.$watch('MSG', function(newValue) {
      $scope.MSG = newValue;
    });
  }]);
}());

Un service:

(function() {

  'use strict';

  var messageServices = angular.module('portal.services');

  messageServices.factory('MessageService', ['MessageData', 'localStorageService', 'UserService'], function(MessageData, localStorageService, UserService) {
    return new MessageService(MessageData, localStorageService, UserService);
  });

  function MessageService(MessageData, localStorageService, UserService) {
    this.messageData = MessageData;
    this.localStorageService = localStorageService;
    this.userService = UserService;
  }

  MessageService.prototype.getMessages = function() {
    var locale = this.userService.getUserinfoLocale();
    var messages = this.localStorageService.get(Constants.key_messages + locale);
    if (messages !== null && messages !== undefined) {
      return JSON.parse(messages);
    } else {
      return this.messageData.query({
        locale: locale
      }, $.proxy(function(data, locale) {
        this.save(Constants.key_messages + locale, JSON.stringify(data));
      }, this));
    }
  };

  MessageService.prototype.save = function(key, value) {
    this.localStorageService.add(key, value);
  };

}());

les données:

(function() {
  'use strict';

  var data = angular.module('portal.data');

  data.factory('MessageData', function($resource) {
    return $resource(Constants.url_messages, {}, {
      query: {
        method: 'GET',
        params: {
          locale: 'locale'
        },
        isArray: true
      }
    });
  });
}());

ordre des fichiers js en tête html:

<script src="js/lib/jquery-1.10.js"></script>
<script src="js/lib/angular.js"></script>
<script src="js/lib/angular-resource.js"></script>
<script src="js/lib/angular-translate.js"></script>
<script src="js/lib/angular-localstorage.js"></script>
<script src="js/lib/jquery-cookies.js"></script>
<script src="js/lib/bootstrap.js"></script>
<script src="js/portal.js"></script>
63
J.Pip

Le problème était d'utiliser la "mauvaise" syntaxe pour créer le service 
à la place d'utiliser:

messageServices.factory('MessageService', 
    ['MessageData','localStorageService', 'UserService'], 
    function(MessageData, localStorageService, UserService){
        return new MessageService(MessageData, localStorageService, UserService);
    }
);

Je devais utiliser:

messageServices.factory('MessageService', 
    ['MessageData','localStorageService', 'UserService', 
    function(MessageData, localStorageService, UserService){
        return new MessageService(MessageData, localStorageService, UserService);
    }
]);

J'ai fermé le tableau avec des paramètres trop tôt et comme je suis encore en train d'apprendre, je ne l'ai pas vu directement. Quoi qu'il en soit, j'espère pouvoir aider les autres qui tombent dessus.

152
J.Pip

Aujourd'hui, j'ai eu le même genre d'erreur en commettant cette erreur stupide:

(function(){

  angular
    .module('mymodule')
    .factory('myFactory', 'myFactory');   // <-- silly mistake 

  myFactory.$inject = ['myDeps'];
  function myFactory(myDeps){
    ...
  }

}());

au lieu de: 

(function(){

  angular
    .module('mymodule')
    .factory('myFactory', myFactory);   // <-- right way to write it    

  myFactory.$inject = ['myDeps'];
  function myFactory(myDeps){
    ...
  }

}());

En fait, la chaîne "myFactory" a été introduite dans l'injecteur qui attendait une fonction et non une chaîne. Cela explique l'erreur [ng: areq]. 

9
Xavier Haniquaut

Les réponses ci-dessus m'ont considérablement aidé à corriger le même problème soulevé dans ma candidature, qui provenait d'une cause différente.

Au moment de la construction, mon application client est en cours de concaténation et de minification; j'écris donc mon angulaire spécifiquement pour éviter les problèmes liés. Je définis ma config comme suit

config.$inject = [];
function config() {
    // config stuff
}

(Je définis une fonction, $inject en tant que module et déclare ce que c'est).

Et puis j'ai essayé d'enregistrer la config comme j'ai enregistré d'autres modules dans mon application (contrôleurs, directives, etc.).

angular.module("app").config('config', config); // this is bad!

// for example, this is right
angular.module("app").factory('mainService', mainService);

C'est faux et m'a donné l'erreur susmentionnée. Alors j'ai changé pour 

angular.module("app").config(config);

Et cela a fonctionné . Je suppose que les développeurs angulaires voulaient config avoir une instance singulière et donc qu'Angular n'accepte pas de nom lorsque config est enregistré.

4
svarog

J'ai eu le même problème et dans mon cas, le problème était avec le fichier angular-cookies.js. C'était dans le dossier avec d'autres scripts angularjs et quand j'ai utilisé gulp pour minifier mes fichiers js, l'erreur est survenue. 

Une solution simple consistait simplement à placer le fichier angular-cookies.js dans un autre dossier, situé en dehors du dossier sélectionné, afin de réduire le nombre de fichiers js.

1
Münich

Mon cas 

  let app: any = angular.module("ngCartosServiceWorker"),
    requires: any[] = [
      "$log",
      "$q",
      "$rootScope",
      "$window",
      "ngCartosServiceWorker.registration",
      PushNotification
    ];
  app.service("ngCartosServiceWorker.PushNotification");

J'ai oublié d'ajouter Array requis en tant que paramètre pour pouvoir servir comme ceci

app.service("ngCartosServiceWorker.PushNotification", requires);
0
spacedev