web-dev-qa-db-fra.com

Comment réparer Angular 2 `Uncaught (promis): TypeError: Impossible de lire la propriété 'query' de null`?

J'utilise le didacticiel Heroes dans la documentation Angular 2 pour expérimenter. Cependant, je suis arrivé à un point où je ne comprends pas ce qui se passe avec cette erreur:

Uncaught (in promise): TypeError: Cannot read property 'query' of null in browser_adapter.ts:88.

Les deux pièces impliquées sont la HeroDetailComponent et la HeroService.

import { Component, OnInit } from '@angular/core'; 
import { RouteParams } from '@angular/router-deprecated';

import { Hero, HeroService } from '../index';

@Component({
    selector: 'my-hero-detail',
    templateUrl: ...
    styleUrls: [...]
})
export class HeroDetailComponent implements OnInit {

    hero: Hero;

    // TEMPORARY FIX:
    _heroService = new HeroService();  // Avoids injection

    // constructor(private _heroService: HeroService,
    //             private _routeParams: RouteParams) {}

    constructor(private _routeParams: RouteParams) {}

    ngOnInit() {
        let id = +this._routeParams.get('id');
        console.log(id);
    }
}

Quand j'utilise ce code, ça marche. Mais lorsque je change de constructeur et que j'utilise celui avec l'injection HeroService, j'obtiens l'erreur mentionnée précédemment.

@Injectable()
export class HeroService {

    getHeroes() {
        return HEROES;
    }

    getHero(id: number) {
        return new Hero(1, 'Name', 'Power', 'AlterEgo');
    }
}

Pendant que j'essayais de comprendre ce qui se passait, j'ai supprimé tout le code relatif aux promesses. Cependant, j'ai toujours la même erreur. Tout se passe bien, c'est une erreur d'exécution. HeroService et RouteParams sont fournis dans un composant parent.

Deux questions:

  1. Comment résoudre ce problème?
  2. Comment déboguer ce genre de problèmes?

J'ai tendance à penser que c'est un bug dans Angular 2, mais je ne sais pas comment faire pour que ce ne soit pas une erreur de ma part. Merci d'avance.

MISES À JOUR:

  1. J'ai ajouté le code de correctif temporaire (qui évite l'injection et ne constitue donc pas une solution à cette question, car j'aimerais que l'injection fonctionne correctement).

  2. Ceci est un Plunker avec une version approximative du code que j'essaie. Je ne pouvais pas le faire fonctionner correctement, mais il peut être utile de diagnostiquer le problème en regardant dans le code.

13
Omar Trejo

Je vois le problème suivant: HeroComponent dépend de HeroDetailsComponent, mais HeroDetailsComponent est exporté afterwards dans le fichier app/heroes/index.ts.

Quelqu'un a signalé un problème avec ce type d'installation ici

12
Martín Coll

Dans le "tsconfig.json", définissez le paramètre "emitDecoratorMetadata" de la section "compilerOptions" sur la valeur "true".

3
kotelok

J'ai eu cette erreur avec RC1 angulaire quand j'injectais FormBuilder dans le constructeur comme ceci:

export class App {
  constructor(public formBuilder: FormBuilder) {}
}

Mais je ne l'avais pas import auparavant! Il suffit d'ajouter que cela résout le problème:

import { FormBuilder } from '@angular/common'

2
bertrandg

Essayez avec ces compilerOptions dans "tsconfig.json". Cela a fonctionné pour moi (version 2.0.0-rc.1 de angular).

"compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "declaration": false,
    "noImplicitAny": false,
    "removeComments": true,
    "noLib": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true   },

J'ai eu le même problème avec les injectables (même erreur) et le correctif a fait l'affaire pour les services mais pas pour http. J'ai modifié mes options sur la base d'un tutoriel de ng-book2 et cela a finalement fonctionné. 

0
GizmoW

Dans mon cas, je résous ce problème en utilisant @Inject décorator. Essaye ça:

import {Inject} from '@angular/core'

constructor(@Inject(HeroService) private _heroService: HeroService,
            @Inject(RouteParams) private _routeParams: RouteParams) {}

Mon projet est configuré avec JSPM et c'est la seule façon de travailler avec l'injection de dépendance, je ne sais pas pourquoi, quelqu'un a une explication?

Edité: j'ai trouvé la solution. Dans mon cas, je dois ajouter cette configuration dans le fichier config.js

System.config({
 baseURL: "",
 defaultJSExtensions: true,
 transpiler: "TypeScript",
 typescriptOptions: {
    "target": "es5",
    "emitDecoratorMetadata": true
 },
 paths: {
    "npm:*": "jspm_packages/npm/*",
 ....

Maintenant je peux enlever le décorateur @Inject et cette phrase fonctionne correctement

constructor(private _heroService: HeroService,
            private _routeParams: RouteParams) {}

La clé est emitDecoratorMetadata: true

0
rulusoft

La réponse correcte à partir de RC1 est d’ajouter la @Inject(Service) private service:Service à chaque fois que vous injectez des services. 

Cela m'a causé beaucoup de maux de tête après ma mise à niveau lundi vers RC1.

0