简体   繁体   English

如何在ngOnInit中使用订阅等待API调用完成?

[英]How to wait for an API call using subscribe to finish in ngOnInit?

Actual Log order: ('ngOnInit started') ('after me aaya', this.policydetails) ('Here', Object.keys(this.policy).length) 实际日志顺序:('ngOnInit开始')('我之后aaya',this.policydetails)('Here',Object.keys(this.policy).length)

Expected Log order: ('ngOnInit started') ('Here', Object.keys(this.policy).length) ('after me aaya', this.policydetails) 预期的日志顺序:('ngOnInit start')('Here',Object.keys(this.policy).length)('after me aaya',this.policydetails)

Component.ts file snippet below: 下面的Component.ts文件片段:

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 file snippet below: 下面的Service.ts文件片段:

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} );
}

JS file snippet corresponding to the API call below: 与以下API调用相对应的JS文件片段:

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});
    });
});

Can anyone please suggest where exactly do i need to async-await for expected log order? 谁能建议我在什么地方需要异步等待预期的日志顺序?

If you want this.makePolicyTable() to be called only after the web request ( getPolicyDetails ) completes, then you should place that call inside of the .subscribe() block: 如果你想this.makePolicyTable()被调用的Web请求(仅后getPolicyDetails )完成,那么你应该把里面的那个呼叫.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();
      });
  });
}

You'll probably also want to move the table logic that's in ngAfterViewInit() inside the subscribe() block, too. 您可能还需要将ngAfterViewInit()的表逻辑也移到subscribe()块内。

Basically, any logic that needs to wait for the asynchronous call to complete should be triggered inside the .subscribe() block. 基本上,任何需要等待异步调用完成的逻辑都应在.subscribe()块内触发。 Otherwise, as you're seeing, it can be run before the web request gets back. 否则,如您所见,它可以在Web请求恢复之前运行。

Finally, I would move this web service call into ngAfterViewInit() instead of ngOnInit() . 最后,我将此Web服务调用移至ngAfterViewInit()而不是ngOnInit() Then you can be sure that the Angular components and views are all set up for you to manipulate them when the web service call completes. 然后,您可以确保在Web服务调用完成时,已全部设置了Angular组件和视图以供您操作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM