【问题标题】:How to wait for an API call using subscribe to finish in ngOnInit?如何在 ngOnInit 中使用 subscribe 等待 API 调用完成?
【发布时间】:2019-02-13 17:59:15
【问题描述】:

实际日志顺序: ('ngOnInit 开始') ('在我之后 aaya',this.policydetails) ('这里', Object.keys(this.policy).length)

预期的日志顺序: ('ngOnInit 开始') ('这里', Object.keys(this.policy).length) ('在我之后',this.policydetails)

Component.ts 文件 sn-p 下面:

ngOnInit() {
    console.log('ngOnInit started');
    this.route.params.subscribe(params => {
      this.getPoliciesService.getPolicyDetails(params.policyNo)
      .subscribe((data: PoliciesResponse) => {
        this.policy = data.data[0];
        this.flattenPolicy();
        console.log('Here', Object.keys(this.policy).length);
    });
    });

    this.makePolicyTable();

  }

  ngAfterViewInit() {
    console.log('after me aaya', this.policydetails);
    const table = this.policydetails.nativeElement;
    table.innerHTML = '';
    console.log(table);
    console.log(this.table);
    table.appendChild(this.table);
    console.log(table);
  }

Service.ts文件sn-p如下:

getPolicyDetails(policyNo) {
  const serviceURL = 'http://localhost:7001/getPolicyDetails';
  console.log('getPolicyDetails service called, policyNo:', policyNo);
  const params = new HttpParams()
    .set('policyNo', policyNo);
  console.log(params);
  return this.http.get<PoliciesResponse>(serviceURL, {params} );
}

下面API调用对应的JS文件sn-p:

router.get('/getPolicyDetails', async function(req, res) {
    let policyNo = (req.param.policyNo) || req.query.policyNo;
    console.log('policyNo', typeof policyNo);
    await helper.getPolicyDetails({'policyNo' : policyNo}, 
        function(err, data) {
            console.log(err, data)
            if (err) {
                return res.send({status : false, msg : data});
            }
            return res.send({status : true, data : data});
    });
});

谁能建议我需要在哪里异步等待预期的日志顺序?

【问题讨论】:

  • getPolicyDetails 您只能在 ngAfterViewInit 内部调用。无需 2 个生命周期

标签: node.js angular typescript angular6


【解决方案1】:

如果您希望仅在 Web 请求 (getPolicyDetails) 完成后调用 this.makePolicyTable(),那么您应该将该调用放在 .subscribe() 块内:

ngOnInit() {
  console.log('ngOnInit started');
  this.route.params.subscribe(params => {
    this.getPoliciesService.getPolicyDetails(params.policyNo)
      .subscribe((data: PoliciesResponse) => {
        this.policy = data.data[0];
        this.flattenPolicy();
        console.log('Here', Object.keys(this.policy).length);

        this.makePolicyTable();
      });
  });
}

您可能还希望将ngAfterViewInit() 中的表逻辑也移动到subscribe() 块内。

基本上,任何需要等待异步调用完成的逻辑都应该在.subscribe() 块内触发。否则,如您所见,它可以在 Web 请求返回之前运行。

最后,我会将这个 Web 服务调用移到 ngAfterViewInit() 而不是 ngOnInit()。然后,您可以确定 Angular 组件和视图都已设置好,以便您在 Web 服务调用完成时对其进行操作。

【讨论】:

    【解决方案2】:

    您还可以在组件中将标志变量设置为 false,然后在异步调用完成时将其设置为 true,并使用 *ngIf 语法基于该标志变量呈现 HTML。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      相关资源
      最近更新 更多