TypeError: undefined n'est pas un constructeur

je suis très nouveau pour Angulaires et j'essaie de comprendre beaucoup de cela encore. J'écris quelques tests en utilisant L'angle 1.5.8 que j'ai généré à partir du générateur de Yeoman.

spécifiquement, j'essaye de comprendre comment manipuler les résultats $httpBackend (Je ne suis pas sûr que ce soit important ou pas)...

Dans mon application.fichier js, j'ai le code suivant:

.run(['$rootScope', '$location', 'breadcrumbService', function ($rootScope, $location, breadcrumbService) {
    $rootScope.$on('$viewContentLoaded', function () {
        jQuery('html, body').animate({scrollTop: 0}, 200);
    });

    $rootScope.isEditMode = false;
    $rootScope.$on('$stateChangeSuccess', function () {
        // ------------ this next line is failing -----------
        $rootScope.isEditMode = $location.path().toLowerCase().endsWith('/edit') || $location.path().toLowerCase().endsWith('/new');
    });

    $rootScope.parseJson = function (value) {
        return angular.fromJson(value);
    };

    $rootScope.bc = breadcrumbService;

    $rootScope.title = "";
}])

la ligne à mi-chemin vers le bas (où j'ai ajouté le commentaire) échoue. Plus précisément, le endsWith la fonction est à l'échec (toLower est très bien), avec cette erreur:

PhantomJS 2.1.1 (Windows 8 0.0.0) Service: breadcrumbService should return breadcrumb label in json format FAILED
        TypeError: undefined is not a constructor (evaluating '$location.path().toLowerCase().endsWith('/edit')') in app/scripts/app.js (line 44)
        app/scripts/app.js:44:72
        $broadcast@bower_components/angular/angular.js:18005:33
        bower_components/angular-ui-router/release/angular-ui-router.js:3353:32
        processQueue@bower_components/angular/angular.js:16383:30
        bower_components/angular/angular.js:16399:39
        $eval@bower_components/angular/angular.js:17682:28
        $digest@bower_components/angular/angular.js:17495:36
        $apply@bower_components/angular/angular.js:17790:31
        done@bower_components/angular/angular.js:11831:53
        handleResponse@bower_components/angular-mocks/angular-mocks.js:1368:17
        flush@bower_components/angular-mocks/angular-mocks.js:1808:26
        test/spec/services/breadcrumbservice.js:33:27
        invoke@bower_components/angular/angular.js:4718:24
        workFn@bower_components/angular-mocks/angular-mocks.js:3085:26

Voici mon code de test (une camelote modifiée à partir de différents exemples - j'essaie juste de la faire fonctionner):

'use strict';

describe('Service: breadcrumbService', function () {

    // load the service's module
    beforeEach(module('myModule'));

    var $httpBackend, $rootScope, createController, authRequestHandler;
    beforeEach(inject(function($injector) {

        $httpBackend = $injector.get('$httpBackend');
        console.log('Is null? '+ ($httpBackend == null));
        $httpBackend.whenGET(/views/.*/).respond(200, [{}, {}, {}]);

        authRequestHandler = $httpBackend.when('GET', '/api/v1/SiteStagings')
            .respond({userId: 'userX'}, {'A-Token': 'xxx'});

        // Get hold of a scope (i.e. the root scope)
        $rootScope = $injector.get('$rootScope');
        $httpBackend.flush();
    }));

    // instantiate service
    var breadcrumbService;
    beforeEach(inject(function (_breadcrumbService_) {
        breadcrumbService = _breadcrumbService_;
    }));

    it('svc should exist', function () {
        expect(!!breadcrumbService).toBe(true);
    });

    it('should return breadcrumb label in json format', function () {
        var result = breadcrumbService.getFromCache('site', 'SiteGroupStagings', 46, 'SiteGroupDesc');
        console.log(result);
        expect(!!result).toBe(true);

    });
});

Je ne doute pas que je fasse quelque chose de mal ici, Je ne peux pas tout à fait comprendre ce que c'est. Qu'est-ce que cette erreur signifie réellement et pourquoi n'aime-t-elle pas mon appel à endsWith?

Merci

20
demandé sur Martin 2016-08-13 06:48:51

4 réponses

"undefined n'est pas un constructeur" un message d'erreur PhantomJS affiche lorsque vous essayez d'appeler une fonction qui n'est pas défini. Cela dépend de la version D'ECMAScript que votre PhantomJS supporte. Donc, comme vous l'avez dit, il fonctionne bien dans Chrome, parce que ce navigateur prend en charge la fonction que vous utilisez dans test. Pour corriger votre problème et pouvoir utiliser PhantomJS, vous pouvez remplacer la fonction" unknown to PhantomJS " par la vôtre.

41
répondu dgraf 2016-12-07 13:17:16

j'ai débattu pour savoir s'il fallait ou non poster ceci comme réponse ou simplement modifier ma question, mais je suppose que c'est ma réponse (pour l'instant):

il semble que le problème soit lié à PhantomJS. Dès que j'ai changé le moteur en Chrome dans le karma.conf.js file, ces tests sont réussis.

Je ne sais toujours pas ce que ce message d'erreur est censé signifier et pourquoi il ne fonctionnait pas avec PhantomJS, mais au moins je suis maintenant en mesure de continuer.

Voici les modifications à mon Karma.conf.js (au cas où quelqu'un est curieux):

browsers: [
 //'PhantomJS',
 'Chrome'
],

// Which plugins to enable
plugins: [
 'karma-chrome-launcher',
 //'karma-phantomjs-launcher',
 'karma-jasmine'
],

Btw - j'ai remarqué que endsWith est nouveau pour ECMAScript6 (je pensais qu'il était plus ancien), mais WebStorm montre qu'il fait référence à une fonction d'aide dans angular-ui-grid. J'ai passé un bon moment de jouer avec le files array dans le karma.conf.js file dans une tentative de voir si la dépendance de l'ui-grille chargeait trop tard ou quelque chose. Dans chaque test, il fonctionnait bien en Chrome, mais pas en PhantomJS. Je n'ai toujours aucune idée de pourquoi.

10
répondu Adam Plocher 2016-08-14 11:39:22

je recevais TypeError: undefined is not a constructor erreur en utilisant le includes() méthode. includes() et endsWith() les méthodes sont nouvelles dans ECMAScript 2015, et ne sont pas supportées dans Internet Explorer, et évidemment pas par PhantomJS.

il est possible que votre utilisateur final utilise Internet Explorer. Dans ce cas, vous pouvez utiliser le support complet indexOf() méthode au lieu de includes() ou endsWith()

par exemple, dans mon cas, tout a bien fonctionné dans chrome, mais mes tests ont échoué sur la ligne:

if (item.name.includes('contents'))

j'ai changé en utilisant la méthode indexOf () à la place:

if (item.name.indexOf('contents') !== -1)

Et puis, je n'étais plus l'obtention de l' TypeError: undefined is not a constructor erreur

8
répondu Hula_Zell 2018-01-02 23:07:29

Dans Mon Cas: Dépendances Cycliques Causant:

PhantomJS 2.1.1 (Windows 8 0.0.0) erreur TypeError: undefined n'est pas un constructeur(evaluating '(0, _actions.prefix) ('SET_USER_INPUT_PHONE_NUMBER')') Non défini:12

j'ai eu la même erreur après avoir ajouté des importations dans mon code de production javascript (syntaxe ES6 compilée avec babel/webpack). Les changements étaient bien quand une construction de production de l'application a été chargée dans chrome mais l'exécution des tests avec phantomJS a produit l'erreur. Dans mon cas, les importations ajoutées ont créé des dépendances cycliques.

je laisse tomber ceci ici pour référence future (je suis tombé sur le même problème il y a quelques semaines et je ne veux pas me gratter à nouveau dans quelques semaines) et pour d'autres qui google la même erreur.

6
répondu Martin 2017-09-06 15:11:44