peckoski
peckoski

Reputation: 115

How can i wait another http call?

I have two buttons

<button (click)="httpOne()">Btn 1</button>
<button (click)="httpTwo()">Btn 2</button>

clicking on the buttons i am triggering a http request. When i click on Btn 1 the http requests needs 10 seconds to be resolved. When i click on Btn 2 the http requests needs 4 seconds to be resolved.

httpOne() {
  this.http.get('some-url-1').subscribe(response => {
  });
}


httpTwo() {
  this.http.get('some-url-2').subscribe(response => {
  });
}

So i first click on button 1, then i click on button 2. I need to wait for the http call from Btn 1 when i click on button 2.

And when the http call is done on Button 1, then i need to start the call on Btn 2.

I know that i can disable the button, but people the client does not want that.I need solution for this because i am struggling with this.

Upvotes: 0

Views: 896

Answers (3)

Joshua McCarthy
Joshua McCarthy

Reputation: 1842

I'm assuming you want this wait to work both ways, regardless of what button is clicked first. We can use a Subject to emit a queue of HTTP requests, and set it up in a way that only one request can be active at a time.

Here's the TypeScript

private httpOne() {
  return this.http.get('some-url-1').pipe(
    map(response=>{})
  );
}

private httpTwo() {
  return this.http.get('some-url-2').pipe(
    map(response=>{})
  );
}

private httpType = new Subject<1 | 2>();

private httpQueueSub = this.httpType.pipe(
  concatMap(type => type === 1 ? this.httpOne() : this.httpTwo()))
).subscribe();

public httpCall(type:1|2){
  this.httpType.next(type);
}

Then in your HTML

<button (click)="httpCall(1)">Btn 1</button>
<button (click)="httpCall(2)">Btn 2</button>

Notice that I've changed httpOne() and httpTwo() to run its response logic inside a map() operator instead of subscribe(). This allows us to declare two observables that can be subscribed to at a later time.

Next we setup a Subject that emits the type of HTTP request we need to make. We then create a single subscription that listens to that subject, and subscribes to either observable based on the Subject's emitted value.

The key operator here is concatMap() which does two important things.

  1. Creates a queue for the HTTP subscription.
  2. Ensures the next item in queue can't start a new HTTP request until the current one is complete.

Now in our HTML, we just need to invoke the function that makes our Subject emit the next HTTP request type.

Upvotes: 0

Amer
Amer

Reputation: 6706

You can achieve that by assigning the first request to Observable then wait for this Observable to emit a value in the second button method like the following:

obs1$: Observable<any>;
httpOne() {
    this.obs1$ = this.http.get('some-url-1');
    this.obs1$.subscribe((response) => {
        // do something here with response
    });
}

httpTwo() {
    // if the obs1$ has a value, then it will wait it to emit a value, then switch to the second request,
    // otherwise, it will switch to the second request directly.
    (this.obs1$ || of(true)).pipe(switchMapTo(this.http.get('some-url-2'))).subscribe((response) => {
        // do something here with second respone
    });
}

Upvotes: 1

Askirkela
Askirkela

Reputation: 1209

You can either do something like this:

class YourComponent {
  btn2Disabled = true;

  httpOne() {
   this.http.get('url1').subscribe({ next: res => this.btn2Disabled = false });
  }
  httpTwo() {
    this.http.get('url2').subscribe(/*...*/);
}

This disables the second button until the first request has returned something but does not trigger the second request.

Or you could do something like this with only one button:

httpOne() {
  return this.http.get('url1');
}

httpTwo() {
  return this.http.get('url2');
}
sequenceRequests() {
  this.httpOne().pipe(
    map(res => /** Do something with the result */),
    switchMap(() => this.httpTwo()),
  ).subscribe({ next: res => /** Do something with the result of the second call */})
}

You can even declare what to do with each result inside the relevant method and just call the first one, switchmap the second, subscribe.

Upvotes: 0

Related Questions