I currently have a function returning an observable that looks a bit like this:
public foo<T>(): Observable<T> {
// Execute some instructions X, Y and Z
return this.http.get<T>(...);
}
So basically, the function executes some instructions before returning an observable that makes an http call.
My issue is that if I do something like this:
const x$ = foo<Type>();
It won't execute the http call (which is normal because I don't subscribe to the observable), however, it will execute the instructions X, Y and Z.
What I would like is to execute these instructions only when I subscribe to the observable, then emit the values from the http call. So far, what I did is:
public foo<T>(): Observable<T> {
return new Observable<T>(observer => {
// Execute some instructions X, Y and Z
const subscription = this.http.get<T>(...).subscribe(observer);
return {
unsubscribe: subscription.unsubscribe
}
}
}
Which works but I feel like something is wrong and that I could do it in a better way.
Is there some recommended way to achieve this?
You can perform your side effects using the tap
operator:
public foo<T>(): Observable<T> {
return this.http.get<T>(...).pipe(
tap(response => {
// Execute some instructions X, Y and Z
})
);
}
However, the above code will only execute your x, y, z AFTER the http response is received.
If you need the x, y, z to happen before the http call is made, you could do something like this:
public foo<T>(): Observable<T> {
return of(undefined).pipe(
tap(() => {
// Execute some instructions X, Y and Z
}),
switchMap(() => this.http.get<T>(...))
);
}
Here we're using of
to fabricate an observable that emits undefined
, then use switchMap
to make the http call and emit the http emission.