Search code examples
angularhttpasync-awaitwait

Wait for HTTP Response before show component


found this question many times. Every time there is another solution. Have tried many of them and nothing has worked. So I asked again:

I try to show a component(part) after load two API requests.

The first request is to check if the user has selected a object.

If he has selected a object he should get what object he has choosen.

If he has not selected a object he should get a list of selectable objects to select one of them.

In first i show the part only if he has selected a objected:

<div *ngIf="alreadySelected">
  You have selected object {{ selectedObject }}
</div>

Here is the Typescript:

    ngOnInit(): void {
    console.log(1);
    this.objectService.getIsObjectAlreadySelected("someuser").subscribe(
      data => {
        console.log(2);
        this.initTheComponent(data);
      }
    );
    console.log(99);
  }
  
  initTheComponent(data: any): void {
    console.log(3);
    if (data.selected) {
      this.objectService.getSelectedObject("someuser").subscribe(
        data => {
          console.log(4);
          this.alreadySelected = true;
          this.selectedObject = data.selectedObject;
        }
      );
    }
    if (!data.selected) {
      this.objectService.findAll().subscribe(
        data => { 
          console.log(5);
          this.alreadySelected = false;
          this.selectableObjects = data; 
        }
      );
    }
  }

And the Service:

  public getSelectedObject(username: String): Observable<any> {
    const url = 'some/url/bar';
    return this.http.get<any>(url, this.httpOptions);
  }

  public getIsObjectAlreadySelected(username: String): Observable<any> {
    const url = 'some/other/url/foo';
    return this.http.get<any>(url, this.httpOptions);
  }

  public findAll(): Observable<MyObject[]> {
    return this.http.get<MyObject[]>("some/other/url");
  }

The problem is that the first API call is needed for the second one.

The console log is following:

1
2
3
99
<some errors because selectedObject is undefined>
4

I try to get the following output:

1
2
3
4
<no errors>
99

I can init the selectedObject as =new MyObject() than the console doesnt print errors. But than the users see at first

 You have selected object

and after some seconds:

 You have selected object someGreatObject

What can I do to wait for both API calls before Angular will show the component(part).

I have already tried await, async, promise, observable, pipe(), .then(), subscribe, subscribe in other subscribe, all combination of them and many other things in last 7 hours. Everybody seems to have another solution. Every solution did not work.


Solution

  • I have a solution which works. It is very simple:

    The used ngIf is my best friend here:

    <div *ngIf="alreadySelected">
      You have selected object {{ selectedObject }}
    </div>
    

    I just set the boolean for ngIf after everything is done inside the callback.

      initTheComponent(data: any): void {
        console.log(3);
        if (data.selected) {
          this.objectService.getSelectedObject("someuser").subscribe(
            data => {
              console.log(4);
              this.selectedObject = data.selectedObject;
              this.alreadySelected = true; // <------------------ set this after setting the date
            }
          );
        }
        if (!data.selected) {
          this.objectService.findAll().subscribe(
            data => { 
              console.log(5);
              this.selectableObjects = data; 
              this.alreadySelected = false; // <------------------ set this after setting the date
            }
          );
        }
      }
    

    Until the boolean is not set, it is undefined. Until it is undefined, the ngIf-part will not be rendered.