【问题标题】:Angular4 - why does promise from service resolve to undefined?Angular4 - 为什么来自服务的承诺会解析为未定义?
【发布时间】:2017-07-31 04:32:08
【问题描述】:

我正在努力解决一个未定义的承诺回报。从我的侦探工作来看,问题似乎是将承诺的结果分配给我调用承诺的组件上的实例变量。我认为这是箭头函数的类型(或类似)问题,我尝试将返回的调查分配给 this.survey。

任何见解将不胜感激!

./survey.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { SURVEYS } from './mock-survey';

export class Option {
constructor(public id: number,
          public text: string,
          public value: number
        ){}
}

export class Question {
constructor(public id: number,
          public type: string,
          public text: string,
          public required: boolean,
          public options: Option[] = []
        ){}
}

export class Survey {
constructor(public id: number,
          public name: string,
          public description: string,
          public instructions: string,
          public questions: Question[] = []
        ){}
}

@Injectable()
export class SurveyService {

  getSurveys(): Promise<Survey[]> {
    return Promise.resolve(SURVEYS);
  }

  getSurvey(id: number | string): Promise<Survey> {
    return this.getSurveys()
      .then(surveys => surveys
      .find(survey => survey.id === +id));
  }

  public observable: Observable<any>;
}

./survey.component.ts

import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit, Inject, HostBinding }      from '@angular/core';
import { MdDialogRef, MD_DIALOG_DATA }  from '@angular/material';
import { Survey, SurveyService } from '../survey.service';

@Component({
  selector: 'app-survey',
  templateUrl: './survey.component.html',
  styleUrls: ['./survey.component.scss'],
  providers: [SurveyService]
})
export class SurveyComponent implements OnInit {

  survey: Survey
  surveyResults: {}

  constructor(
    private surveyService: SurveyService,
    public dialogRef: MdDialogRef<SurveyComponent>,
    @Inject(MD_DIALOG_DATA) public data: any
  ) { }

  // getSurveys(): void {
  //   this.surveyService.getSurveys().then(
  //     surveys => this.surveys= surveys);
  // }


  // *This method also returns an undefined this.survey; Not issue with ngOnInit()
  // getSurvey(): void {
  //   let survey_id = this.data.survey_id
  //   this.surveyService
  //       .getSurvey(survey_id)
  //       .then(s => {this.survey = s});
  // }

  ngOnInit(): void {
     this.surveyService
      .getSurvey(this.data.survey_id)
      .then((survey: Survey) => {this.survey = survey});

    // returns survey_id from MD_DIALOG_DATA
    console.log(this.data.survey_id)
    // returns survey JSON object; This arrives in browser console
    console.log(this.surveyService.getSurvey(this.data.survey_id));
    // returns undefined
    console.log(this.survey);
  }

  confirmSurveyResults() {
    this.dialogRef.close(this.surveyResults);
    console.log(this.survey);
  }


}

【问题讨论】:

标签: angular typescript promise angular-services arrow-functions


【解决方案1】:

Promise 是异步的,因此调查将始终在 ngOnInit 方法的上下文中未定义:

  ngOnInit(): void {
     this.surveyService
      .getSurvey(this.data.survey_id)
      .then((survey: Survey) => {
         this.survey = survey
         console.log(this.survey);// here it WILL NOT be undefined
       });


    // returns undefined because the promise is not fulfilled yet
    console.log(this.survey);
  }

【讨论】:

  • 感谢您的回复和澄清。现在这是有道理的,为什么它在 ngOnInit 中返回 undefined。但是,我仍然有一个问题。箭头函数分配在 ngOnit 之外不起作用。调查对象在模板中不可用。当我添加 *ngIf="survey" 如果返回 falsy 并且我得到一个空白模板。如果我删除 *ngIf="survey 并尝试访问 {{survey.name}},然后我会得到 ERROR TypeError: Cannot read property 'name' of undefined。这似乎是一个角度问题。我可能在某处遗漏了一个细节。想法?
【解决方案2】:

如前所述,调查尚未在 init 进行。当您加载 html 时,它仍然不存在,因此您必须确保调查存在,然后才能在 ngfor 之类的东西中使用它。

也许使用 ngIf?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 1970-01-01
    • 2017-07-23
    • 2021-01-28
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多