Проблема с обещанием Angular 2

Я начинаю изучать Angular 2, и у меня возникают проблемы с использованием Promise.then для возврата моего объекта из службы. В настоящее время я использую только фиксированный массив (COACHES) для имитации вызова базы данных. Функция в моем сервисе выглядит следующим образом

getCoach(id: number) {
    return Promise.resolve(COACHES).then(
        coaches => coaches.filter(coach => coach.id == id)[0]
    );
}

Затем я использую это в моем coach_detail.component.ts в хуке ngOnInit, чтобы получить объект тренера, который я хочу, используя параметры маршрута:

export class CoachDetailComponent implements OnInit {

    coach: Coach;

    constructor(
        private _coachService: CoachService,
        private _routeParams: RouteParams) {}

    ngOnInit() {
        let id = +this._routeParams.get('id');
        this._coachService.getCoach(id).then(coach => this.coach = coach);
        console.log(this.coach);
    }
}

Я вижу в своей консоли, что обещание возвращается обратно в мой компонент, но console.log(this.coach) возвращается как undefined

Любая помощь очень ценится, так как я использую аналогичную логику в другом компоненте, чтобы вернуть весь список тренеров, и это отлично работает!


person Andrew Hamilton    schedule 28.02.2016    source источник


Ответы (1)


Ваш console.log() вызывается до выполнения цепочки обещаний.

ngOnInit() {
    let id = +this._routeParams.get('id');
    this._coachService.getCoach(id).then(coach => { 
      this.coach = coach 
      console.log(this.coach); // not undefined
    });
    console.log(this.coach); // undefined
}
person Sasxa    schedule 28.02.2016
comment
Но разве я не вызываю console.log для переменной тренера, которую я определил в компоненте? this._coachService.getCoach(id) должен назначать возвращаемый объект this.coach. Моя проблема действительно в том, что моя функция стрелки не назначается должным образом - person Andrew Hamilton; 28.02.2016
comment
Хм, ваш код выглядит нормально. Можете ли вы создать плункер с примером? - person Sasxa; 28.02.2016
comment
Немного громоздко, но вот:plnkr.co/edit/Sk4GH2mgoJ2XkQ7Tr1qN Проблема, о которой я говорю, это когда вы переходите на страницу «Тренеры» и затем пытаетесь выбрать имя тренера. - person Andrew Hamilton; 28.02.2016
comment
Проблема возникает из-за того, что вы используете coach до того, как он будет назначен. При создании компонента и до вызова ngOnInit() шаблон пытается получить доступ к этой переменной. Вы можете использовать оператора Элвиса в своем шаблоне <h1>{{coach?.first_name}} {{coach?.surname}}</h1> plnkr.co/edit/p4YEbGUVs2jPQ2gJpi9n - person Sasxa; 28.02.2016
comment
вижу большое спасибо. Есть ли что-то еще, что я мог бы сделать, чтобы мне не пришлось использовать оператора Элвиса? Или это стандартная практика? Я заметил, что в учебнике по ang2 вместо этого используется ngIf. - person Andrew Hamilton; 28.02.2016
comment
Можно попробовать не отображать данные напрямую (путь ng1) и использовать прокси - какой-нибудь app state. Таким образом, ваш слой просмотра (шаблоны) будет отображать только то, что находится в app state, а ваши сервисы будут предоставлять данные для app state. - person Sasxa; 28.02.2016
comment
Взгляните на @ngrx/store, это реализация шаблона редукции для ng2. Поначалу это может быть немного ошеломляюще, но стоит каждого часа (или недели :), потраченного на попытки понять это (; - person Sasxa; 28.02.2016
comment
Спасибо. Последний вопрос, тогда я оставлю вас в покое! Почему нам нужно использовать ? в этом примере, но нам не нужно делать это для всего списка тренеров, где я использую *ngFor="coach of coaches" означает ли ngFor, что он не пытается получить доступ до тех пор, пока не будет выполнен ngOninit? - person Andrew Hamilton; 28.02.2016
comment
Просто так ngFor работает - у него есть некоторые внутренние проверки if (isBlank(this._differ) && isPresent(value))... - person Sasxa; 28.02.2016