I have two observable data streams. One retrieves an account, one gets permissions.
What I need to do is check if the current user has the role of admin, or has the role of external and the current account does not have a flag set. But how to do that with rxjs is eluding me.
Here is a stripped down test case to show what I'm trying to do, but because all of the data isn't there when it runs (either the account is null, or the permissions haven't been loaded yet), it errors out.
How can I make this work?
I'm using rxjs6.
export class ViewComponent implements OnInit {
private account: AdminUser;
private permissions: Permissions;
constructor(private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute) {
}
canEdit(): boolean {
let isAdmin = this.permissions.hasRole('Admin');
return isAdmin || (this._permissions.hasRole('External') && !this.account.isActiveDirectory);
}
ngOnInit() {
this._permissions
.getPermissions()
.subscribe(p => this.permissions = p);
this._activatedRoute.params.subscribe(
params => {
this._service.get(params.id)
.pipe(map(account => this.account = account))
.subscribe();
});
}
}
You can leave your data as observables without subscribing in your component. Rxjs has many operators and static functions to shape, filter, and transform them to suit your needs.
Instead of defining
accountasAdminUserandpermissionsasPermissions; let's define them asObservable<AdminUser>andObservable<Permissions>.We can then use
combineLatestthe create a single observable that emits thecanEditvalue.If you aren't familiar with
switchMap, it basically subscribes to an "inner observable" for you and emits the result(s). In this case, taking theidand making the call toservice.get(id).It seems likely you'll also want to use the account info in your template along with the
canEditvalue. Instead of emitting a singleboolean, we can emit an object that contains all the data our view needs (a view model):You can now use a single
asyncpipe in your template to handle the subscribing for you: