I have a service with http request which return Observables of my Headlines
servise.ts
get(sort: string): Observable<Response> {
return this.http.get<any>(this.url, {...});
})
delete(id) {
return this.http.delete(`${this.url}/${id}`, {...});
}
and in my component I have a function that set this.headlines
from service get request. It looks like this:
interface IRes {
searches: {
label: string,
id: number,
value: string,
...
}
}
headlines = [];
loadHeadlines() {
this.service.get(data).subscribe((res: IRes) => this.headlines= res.headlines);
}
The problem is that sometimes I receive headline with empty label and don't need to show them, so I need to filter it and send.delete() request for this headlines. I tried something like this( The idea was to add .pipe
before subscribe
and call inside another subscribe.) Something like that
loadHeadlines() {
this.service.get(data)
.pipe(
map(res: IRes => {
res.headlines.filter(headline => !!headline.label.trim())
.forEach(headline => this.service.delete(headline.id).subscribe())
})
)
.subscribe((res: IRes) => this.headlines= res.headlines);
}
but not sure that it's good idea. Which method would be better here?
You could use RxJS switchMap
operator to map from one observable to another and forkJoin
function to combine multiple observables. I've also used iif
(with of
) function to check if there are any empty headline
s to be deleted.
But I fail to understand the condition you're using at the moment. It seems you're removing all the headline
elements with empty label
property while invoking delete
on the rest. So essentially you're calling delete
on all the valid elements. Perhaps it must be adjusted.
Try the following
import { iif, forkJoin, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
loadHeadlines() {
this.service.get(data).pipe(
switchMap((res: IRes) => {
const emptyHeadlines = res.headlines.filter(headline => !headline.label.trim()); // <-- all headlines with empty labels
const deletes$ = forkJoin(
emptyHeadlines.map(headline => this.service.delete(headline.id))
).pipe(
map(_ => ({ // <-- map back to return only the headlines with defined `label`
...res,
headlines: headlines.filter(headline => !!headline.label.trim())
}))
);
return iif(
() => !!emptyHeadlines.length,
deletes$, // <-- execute delete only if there are empty headlines
of(res) // <-- if not forward the response
);
})
).subscribe(
(res: IRes) => this.headlines = res.headlines,
(error: any) => console.log(error)
);
}
well, ..headline.label.trim()
definitely isn't a good idea, because the double !
will delete all headlines that are NOT empty. also that map
should be a tap
.
so for the complete pipe:
this.service.get(data).pipe(
map(res => res.headlines)
tap(headlines => headlines.filter(headline => !headline.label.trim()).forEach(
headline => this.service.delete(headline.id)
)),
map(headlines => headlines.filter(headline => !!headline.label.trim())),
).subscribe(headlines => this.headlines= headlines);
In a real scenario, i'd leave this to be handled by the backend. But tbh, this is strongly opinionated, as there is no objective right/wrong here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.