Reputation: 314
Scenario: I have an Angular service that exposes an object that will change over time, let's call it User. A User has some properties that will also change over time, let's call it Friends.
The User and Friends may be fetched from the server at times, and I would like to merge this information into a single User observable.
Essentially, this:
interface User {
name: string;
friends: Friend[];
}
class MyService {
private userSubject = new Subject<User>();
private newFriendSubject = new Subject<Friend>();
user: Observable<User>; // Consumers will subscribe to this
constructor() {
// Here, user should be set up to merge the two subjects
this.user = ...
}
fetchUser() {
fetchUserFromServer().subscribe(user => this.userSubject.next(user))
}
addFriend(f: Friend) {
addFriendServerRequest(f).subscribe(newFriend => this.newFriendSubject.next(newFriend))
}
Now, I would like to combine values from the User subject, with ones from the Friends subject, so that they represent a User with Friends.
Question: How do I do this? I'm thinking I should use some combination of merge
and scan
:
this.user = merge(this.userSubject, this.newFriendSubject).pipe(
scan((user, userOrFriend) => {
if (userOrFriend is User) return userOrFriend
else return {...user, friends: [...user.friends, userOrFriend]}
})
)
...But this doesn't really work, because scan
needs the accumulator (user) and the value (userOrFriend) to be of the same type. Am I going at this the wrong way, or is there some operator/pattern I'm missing?
Kind of a generic question, but I could really use some help from somebody with some rxjs expertise.
Upvotes: 0
Views: 4572
Reputation: 1515
To conform to latest documentation.
const u = combineLatest(this.userSubject, this.newFriendSubject);
u.subscribe(([user, friends]) => {
this.user = ...
});
Upvotes: 0
Reputation: 9392
You can use the combineLatest operator
this.user = combineLatest(this.userSubject, this.newFriendSubject)
subscribe(([user, friends]) => {
//do something here
})
Upvotes: 1