I'm trying to return an observable when I get a certain value in a subscriber, but I fail miserably.
This is the code:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
// get route to be activated
this.routeToActivate = route.routeConfig.path;
// get user access levels
return this._firebase.isUserAdmin <-- returns Subscription, not Observable
.map(user => user.access_level)
.subscribe( access => {
// I need to return an observable here
});
}
There are not many resources on observables in angular 2, so I don't know where to start. Can anyone help with this please?
UPDATE -> Working Version
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
// get route to be activated
this.routeToActivate = route.routeConfig.path;
// get user access levels
return this._firebase.isUserAdmin
.map(user => {
let accessLevel = user.access_level;
if (accessLevel === 'admin' ) {
return true;
}
}).first();
}
Use operators to combine observables (not sure which one will be suitable in your case, possibly switchMap), then subscribe to resulting observable. Since you're dealing with things that cannot fully benefit from observables, it may be reasonable to switch to promises (async..
Subscriptions to observables are quite similar to calling a function. But where observables are different is in their ability to return multiple values called streams (a stream is a sequence of data over time). Observables not only able to return a value synchronously, but also asynchronously.
The subscribe() call returns a Subscription object that has an unsubscribe() method, which you call to stop receiving notifications.
You can't return an observable from subscribe but if you use map
instead of subscribe
then an Observable
is returned.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
// get route to be activated
this.routeToActivate = route.routeConfig.path;
// get user access levels
return this._firebase.isUserAdminObservable
.map(user => {
// do something here
// user.access_level;
return true;
})
.first(); // for the observable to complete on the first event (usually required for `canActivate`)
// first needs to be imported like `map`, ...
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
// get route to be activated
this.routeToActivate = route.routeConfig.path;
let subject = new Subject();
// get user access levels
this._firebase.isUserAdminObservable
.map(user => {
let accessLevel = user.access_level;
if (accessLevel === 'admin' ) {
subject.emit(true);
subject.complete();
}
return user;
});
return subject;
}
Couldn't we just use pipe
with map
from import { map } from 'rxjs/operators';
?
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class SearchHostService {
constructor(private readonly http: HttpClient) {}
searchForHosts(searchString: string): Observable<Employee[]> {
return this.http
.get<Employee[]>('./assets/host-users.json')
.pipe(
map(employees =>
employees.filter(({ displayName }) =>
displayName.toLowerCase().startsWith(searchString),
),
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With