简体   繁体   中英

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)

Expected Log order: ('ngOnInit started') ('Here', Object.keys(this.policy).length) ('after me aaya', this.policydetails)

Component.ts file snippet below:

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:

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:

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:

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.

Basically, any logic that needs to wait for the asynchronous call to complete should be triggered inside the .subscribe() block. Otherwise, as you're seeing, it can be run before the web request gets back.

Finally, I would move this web service call into ngAfterViewInit() instead of 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.

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

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