Wait for Service Api call to complete in Angular 8

ⅰ亾dé卋堺 提交于 2021-02-11 15:26:53

问题


I am trying my first Angular 8 Crud Web app and wrote a page to list some company names from WebApi

My Service is correctly getting data and Iam able to print it on console

//Service.ts
export class CompanyService {
  allCompanys: Company[]
  constructor(private httpClient: HttpClient) { }
  // Returns all the companys
  GetAll(): Company[] {

    this.httpClient.get<Company[]>('https://localhost:565656/api/company').subscribe(result => {
      this.allCompanys = result;

      //Shows data Sucessfully from Server :Working fine
      console.log(this.allCompanys);

    }, error => console.error(error));

    return this.allCompanys;
  }

But in my component I try to get the data at the starting of page by calling the service and assign it to local varaible it is giving undefined

     ///Component.ts

      export class CompanyListComponent implements OnInit {
      Companylist: Company[] 
 constructor(private route: ActivatedRoute, private router: Router, private companyService: CompanyService) {  }
        ngOnInit() {

          this.Companylist = this.companyService.GetAll();  
          //This is executing before the service call is returning and returning Undefined
          console.log("At Component " + this.Companylist)

        }

My html look likes below and table not showing

  //html

      <tr *ngFor="let company of Companylist">
      <td>{{company.Name}}</td>
      <td>{{company.Phone}}</td>
      <td>{{company.Email}}</td>
      <td>{{company.Address}}</td>
       < /tr>

I tried Observables also but not working.I need the variable to bind after the api is called.Can somebody advice what I am doing wrong

I had already checked the similar cases in SO and cant find something similar(may be not understanding to me)


回答1:


http request is done as asynchronous operation so will start requesting but the execution of getAll asynchronous so will immediately get to the return statement and return what every allCompanys has.

to solve this you need to update GetAll to return an observable

GetAll(): Observable<Company[]> {
   return  this.httpClient.get<Company[]>('https://localhost:565656/api/company')
}

at the component you subscribe to the getAll

this.companyService.GetAll().subscribe( result=> this.Companylist = result ); 

and we can simplify the above code with async pipe

Companylist$ : Observable<Company[]>;

ngOnInit(){

Companylist$ = this.companyService.GetAll();

}

template

<tr *ngFor="let company of Companylist$ | async">
...
</tr>

async pipe subscribes to the observable and returns the latest value it has emitted.

🌟 another way is to use async/await, so we need to update GetAll to return a promise and it is very easy to convert observable to promise with toPromise method

GetAll(): Promise<Company[]> {
   return  this.httpClient.get<Company[]>('https://localhost:565656/api/company')
          .toPromise(); // 👈
}

componnet

async ngOnInit() {

  this.Companylist = await this.companyService.GetAll();  
   ...
}

read more about it here 👉 async/await




回答2:


The problem is because you are returning this.allCompanys before async call this.httpClient.get<Company[]>('https://localhost:565656/api/company') gets resolved.

You can either return an Observable Company[] like return this.httpClient.get('https://localhost:565656/api/company') and catch it in your view like allCompanys | async or you could remove that return Company[] type from your method and replace it for a void, remove the return and let this.allCompanys = result like it is in the subscription so you could also control it's value (when it gets resolved) like if (this.allCompanys) { // Do something }




回答3:


Easiest code for you to understand

In your component ts:

ngOnInit() {
    // callback gets executed when your service gets the response in the API call
    const callback = function(companyList: Company[]) {
      this.Companylist = companyList;
    }
    this.companyService.GetAll(callback);
    console.log("At Component " + this.Companylist)
}

In your service ts:

GetAll(callback?: Function) {

    this.httpClient.get<Company[]>('https://localhost:565656/api/company').subscribe(result => {
      this.allCompanys = result;

      //Shows data Sucessfully from Server :Working fine
      console.log(this.allCompanys);
      if(callback) {
        callback(this.allCompanys);
      }

    }, error => console.error(error));
}



回答4:


In the service, this.allCompanys is returned synchronously even before you get the response. So it returns Undefined. But when the response comes, the component no longer checks the update.

So You need to update the value asynchronously.

GetAll(): Company[] {
    return this.httpClient.get<Company[]>('https://localhost:565656/api/company');
}

in component

this.companyService.GetAll().subScribe((res) => {
    this.Companylist = res;
}, error => console.error(error)
)


来源:https://stackoverflow.com/questions/59171532/wait-for-service-api-call-to-complete-in-angular-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!