5

Is there a way to resend an HttpRequest when using the async pipe in the template like this?

myObservable$ = this.http.get('api');
<div *ngFor='let item of myObservable$ | async'>{{item}}</div>

3 Answers 3

7

You need emit a new value to Observable, if you need refetch data by specific event, you can put the event to Observable and use switchMap for trigger fetching:

event$ = new BehaviorSubject(true);

myObservable$ = this.event$.pipe(
  switchMapTo(this.http.get('api'))
);

refetchData() {
  this.event$.next();
}

Sign up to request clarification or add additional context in comments.

1 Comment

I would also move the event$.next() on the event itself in the template. This is also what I had in mind when I asked the question, and it seems like the only efficient solution to a reactive architecture.
2

Using async pipe is a very convenient way to deal with Observables, because it manages unsubscribing for you. Meaning, that if myObservable$ reference changes, ChangeDetection will be triggered and async will unsubscribe current subscription and subscribe to another. So you can simply reassign new value myObservable$ and HttpRequest will be sent again.

test it out yourself:

ngOnInit() {
  setTimeout(() => this.myObservable$ = this.http.get('another-endpoint'), 2000)
}

6 Comments

Although a good workaround, I think this approach violates the reactive pattern, which should be used when working with async pipe
Why would you think so? IMO is a legit way
Reassigning the observable is imperative, not declarative. Please correct me if i'm wrong.
@Bogdan B Declarative programming means you express what you would like to do, while leaving the how to the language or framework. Imperative programming means you tell it step by step how to do something. Variable reassignment doesn't have anything to do with declarative or imperative programming. One great example of declarative programming is the SQL language
I dont think reassigning a variable in general is either declarative or imperative. By reassigning to a new Observable we do just that. And rest of the logic is being done without our interference - async does the work for us, we don't need to give any more instructions. So for this code snippet it appears to be even more declarative
|
0

This is not the best practice. The async pipe is meant to be used with streams, using it with trigger observables such as http calls can have unwanted side effects. I suggest putting the http call in a service, and subscribing in your component. If there's a specific reason you want to use the async pipe, I suggest having a separate BehaviorSubject and doing something like this....

_myBehaviorSubject = new BehaviorSubject(null);
myBehaviorSubject$ = this._myBehaviorSubject.asObservable();

myObservable$ = this.http.get('api').pipe(tap(items => this._myBehaviorSubject.push(items)));

Then, in your component, you can subscribe to this every time you want to make an http call, and in your html template, subscribe to myBehaviorSubject$ using the async pipe.

1 Comment

Most examples of http calls on Angular docs are made using an observable and async pipe. Why would it be bad practice if I want fresh data, but I also want Angular to take care of unsubscribing and having a reactive architecture.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.