Angular - How to check for pending requests?

Viewed 4192

I have the following host component and a child component in my app.

@Component({
  selector: 'ng-host',
  templateUrl: '<div><router-outlet></router-outlet></div>'
})
class HostComponent {
  constructor(
    private ressourceService: RessourceService
  ) {
    this.ressourceService.GetRessource().subscribe();
  }
}

@Component({
  selector: 'ng-child',
  templateUrl: '<div></div>'
})
class ChildComponent {
  constructor(
    private ressourceService: RessourceService
  ) {
    if (this.ressourceService.ressource === null) {
      this.ressourceService.GetOtherRessource().subscribe();
    }
  }
}

They both inject the same service for a ressource:

@Injectable()
class RessourceService {
  public ressource: any;

  constructor(private http: HttpClient) { }

  GetRessource() {
    return this.http.get('url').pipe(
      map(response => this.ressource = response.ressource)
    );
  }
  GetOtherRessource() {
    return this.http.get('otherUrl');
  }
}

Usually the user will login, land at the host component and naturally navigate through the app, until he reaches the child component. Since the Host component is already instantiated, the child component can check, if the ressource is loaded and load the other ressource only if it's not. Everything works as it should.

But if I reload the page, both the host and the child component will be loaded simultaneously. Since the request from the host component is still pending and the ressource of the service is not yet set, the child component will assume that the ressource doesnt exist and will load the other ressource.

How can I prevent that? Is there a way to check, if any requests are still pending? Is it possible to chain these two requests, if they are called in different components? Or do I need to overhaul the structure of my app?

1 Answers

You can "cache" the responses in the service

@Injectable()
class RessourceService {
  public resource1: any;
  public resource2: any;

  constructor(private http: HttpClient) { }

  GetRessource() {
    if (!resource1)
       return this.http.get('url').pipe(
        map(response => response.resource), //not return response, just response.resource
        tap(response=>this.resource1=response)  //when subscribe store the response
    )
     else
        return of(this.resource1)
  }
  GetOtherRessource() {
    if (!resource2)
       return this.http.get('otherurl').pipe(
        map(response => response.resource),
        tap(response=>this.resource2=response)
    )
     else
        return of(this.resource2)
  }
}

Then, you always subscribe to GetResponse and GetResponse2

Related