Reputation: 3714
Is is possible (I can't find anything comprehensive on this) to combine multiple pipable operators in one function, so I can pipe it and re-use in a different method as well?
Here is the thing:
public ngOnInit(): void {
this.route.url
.pipe(
switchMap( (ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
How do I extract everything within pipe()
so I can call the same chain of operators from a different method, which would need to perform the same http call and subsequent logic and manipulating?
What I try to achieve is:
this.route.url
.pipe(
this.combinedPipableMethod(url: UrlSegment[])
)
.subscribe()
Upvotes: 1
Views: 709
Reputation: 725
You can use rxjs pipe
( Notice, it's a standalone function, not the method of the Observable) function to combine a sequence of operators into one reusable operator.
import { pipe } from "rxjs";
const customPipable = pipe(
switchMap( (ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
this.route.url
.pipe(customPipable)
.subscribe()
Upvotes: 5
Reputation: 2987
You can store the chain within a Subject
, then simply call next()
on the subject to force the pipeline to run
//Subject for storing pipeline
loadDataSubject = new Subject();
ngOnInit() {
loadDataPipe(this.loadDataSubject).subscribe(
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
)
}
loadDataPipe(source) {
return source.pipe(
switchMap( (ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
}
Now feel free to invoke the pipeline run again wherever you feel like with next()
:
....
this.loadDataSubject.next();
....
Upvotes: 0
Reputation: 998
You could extract a method:
getData(ids: UrlSegment[]) {
return this.http.get(/* url construction logic */)
.pipe(
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
);
}
And then switchMap
to it:
public ngOnInit(): void {
this.route.url
.pipe(
switchMap(this.getData),
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
Otherwise, you could make a custom operator but it seems like overkill for this purpose:
const combinedPipableMethod = () => {
return source => defer(() => {
return source.pipe(
switchMap((ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
})
}
public ngOnInit(): void {
this.route.url
.pipe(
combinedPipableMethod(),
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
Upvotes: 4