I need to create an Observable that will collect other observables coming from some http requests. The new observable must be a collection of same object type but every item must be unique. Can you help me writing the correct method to achieve this goal?
// The result observable that I need
topicCollection$ = BehaviorSubject<Topic[]> = new BehaviorSubject<Topic[]>(null);
// Boolean observable of authentication
isAuthenticated: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
// Return default topic
get defaultTopics$(): Observable<Topic[]>{
return this.defaultTopic.asObservable();
}
// Return topics selected by Admin
get TopTopics$(): Observable<Topic[]>{
return this.topTopic.asObservable();
}
//Return topics selected by User
get userTopics$: Observable<Topic[]>{
return this.userTopic.asObservable();
}
//Return user settings
get userSettings$(): Observable<any[]>{
return this.userSettings.asObservable();
}
So the constraint are:
I try with combineLatest and forkJoin but I don't know how to differenziate the operators with the authentication observer.
You can try something like this. Of course since your question isn't complete, neither is this answer.
You'll have to implement a few parts yourself. Still, the following should be a decent place to start tinkering.
get topicCollection$(): Observable<Topic[]> {
return this.isAuthenticated.pipe(
take(1),
switchMap(isLogged => {
// The easy part, merge arrays emitted from two separate streams
const mergeDefaultTop$ = forkJoin([
this.defaultTopics$.pipe(take(1)),
this.topTopics$.pipe(take(1))
]).pipe(
map((v: Topic[][]) => v.flat())
);
// If the user is logged in, merge then filter the merged topics.
return !isLogged ? mergeDefaultTop$ : mergeDefaultTop$.pipe(
switchMap(topics => this.userTopics$.pipe(
map(userTopics => [...topics, ...userTopics])
)),
switchMap(topics => this.userSettings$.pipe(
map(settings => topics
// You'll want to update this filter. I can't define it for you
// as I dont know what a topic is/ how it's labled, etc.
.filter(topic => topic !in settings)
// Filter to remove duplicats. You may want to better define
// equality depending on your use case (again, I can't do
// that for you with what you've provided)
.filter((value, index, self) =>
self.indexOf(value) === index
)
)
))
);
})
);
}