简体   繁体   中英

Angular 2 rc1 component initialization

I am experimenting with Angular 2 rc1 and have a very simple component. As displayed it fails:

import { Component, OnInit }    from '@angular/core';
import { Http, Response }       from '@angular/http';
import { Observable }           from 'rxjs/Observable';
import { Movie }                from "./movie";
import { MovieService }         from "./movieService";

import "rxjs/add/operator/map";

@Component
({
    selector: 'my-app',
    template: `
        <p>{{mov.Rating}}</p>
        <ul>
          <li *ngFor="let movie of movies" >
            {{movie.Title}} - {{movie.Rating}}
          </li>
        </ul>
        `,
    providers: [MovieService]
})

export class AppComponent implements OnInit
{
    public name: string;
    public mov: Movie;// = { Title: "bla", Rating: 3 };
    public movies: Movie[];

    constructor(private movieService: MovieService) {}

    public ngOnInit()
    {
        this.movieService.getMovies()
            .subscribe(movies =>
            {
                this.movies = movies;
                this.mov = this.movies[1];
            });
    }
}

If I do initialize the mov variable (and no other change) it will work just fine.

When it fails, the browser (chrome, firefox or IE) throws an exception ("TypeError: Cannot read property 'Rating' of undefined") and ends execution. MovieService does an actual API call which takes a few milliseconds and during that time mov is indeed undefined. In Angular1 that was not a problem; it would simply display nothing.

I tried making the movieService call in the constructor but that made no difference.

Is that intended behavior, a bug or am I missing something and there is a way to prevent it (except initialization of the mov variable)?

This is intended behavior. As you already noted the mov variable is indeed undefined when the component is initialized. Therefore Angular can't read the Rating property of mov . Only when the API call returns, the mov variable is filled.

You could indeed initialize the variable in the constructor. Another, perhaps cleaner way is to use the Elvis operator in your template:

 <p>{{mov?.Rating}}</p>

The Elvis operator guards against null (/uninitialized) values.

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