Reputation: 101456
In my code I am getting a list of users from MS Graph, but this lists all users. I want to emit only those users that are a member of a specified group. So I have set up a filter:
private loadUsers() {
console.log(`Loading users...`);
this.graph.get$(`users`)
.map(resp => resp.json().value)
.flatMap(user => user)
.do(user => {
console.log(`Got user: ${user['displayName']}`);
})
.filter(user => {
// we only want users who are members of the TrackerContact group
const userId: string = user['id'];
console.log(`Checking user ${userId}`);
return this.userIsTrackerContact(user); // <<= PROBLEM HERE!
})
.subscribe(_ => {
console.log(`Completed user fetch!`);
});
}
The problem is in order to find out what groups a user is a member of, I must make another REST call back to MS Graph:
private userIsTrackerContact(user): Observable<boolean> {
// get the groups this user is a member of
return this.graph.get$(`users/${user['id']}/memberOf`)
.map(resp => resp.json().value)
.do(groups => {
console.log(`${user['displayName']} is a member of ${groups.length} groups:`);
groups.forEach((group, idx) => {
console.log(` [${idx+1}]: ${group['displayName']}`);
})
})
.map(groups => {
const found = groups.find((group) => group['id'] === this.authConfig.azureGroups.trackerContact)
return !isUndefined(found);
})
}
It does not seem to me that it's possible to filter an Observable based on another observable. The predicate test must be a simple true/false test.
How can I filter an Observable based on the results of another Observable?
Upvotes: 0
Views: 1857
Reputation: 82614
.concatAll() might be better:
this.graph.get$(`users`)
.map(resp => resp.json().value)
.flatMap(user => user)
.do(user => {
console.log(`Got user: ${user['displayName']}`);
})
.filter(user => {
// we only want users who are members of the TrackerContact group
const userId: string = user['id'];
console.log(`Checking user ${userId}`);
return this.userIsTrackerContact(user); // <<= PROBLEM HERE!
})
.concatAll()
.subscribe(...)
I believe you should be able to merge the async observables then filter.
Rx.Observable.merge(this.graph.get$(`users`)
.map(resp => resp.json().value)
.flatMap(user => user)
.do(user => {
console.log(`Got user: ${user['displayName']}`);
})
.map(user => {
// we only want users who are members of the TrackerContact group
const userId: string = user['id'];
console.log(`Checking user ${userId}`);
return this.userIsTrackerContact(user); // <<= PROBLEM HERE!
}))
.filter(x => x)
.subscribe(_ => console.info('success'));
You can change your predicate set a property on user isGroupMember. Then filter(x => x.isGroupMember)
. Then you have the user objects in the subscribe method.
Upvotes: 1