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: Activated
Do this if you want to subscribe to observable, process the result and then return the same result in subscribe:
function xyx(): Observable<any> {
const response = someFunctionThatReturnsObservable().pipe(map(result => {
// here do any processing of the result //
return result; // return back same result.
}
))
return response;
}
You don't need map, code below specifies a predicate and a projection function for first.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
this.routeToActivate = route.routeConfig.path;
return this._firebase.isUserAdminObservable
.first((_, index) => index === 0, user => {
// do something here
// user.access_level;
return true;
})
}
More on first
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;
}
We can convert the Observable object to promise using toPromise
method.
so the code can be implemented as followed:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Promise<boolean> {
// get route to be activated
this.routeToActivate = route.routeConfig.path;
// get user access levels
return this._firebase.isUserAdmin
.map(user => {
return (user.access_level === 'admin');
}).toPromise();
}
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 http: HttpClient) { }
searchForHosts(searchString: string): Observable<Employee[]> {
const res = <Observable<Employee[]>>this.http.get('./assets/host-users.json');
const result = res.pipe(
map(val =>
val.filter(emp => emp.displayName.toLowerCase().startsWith(searchString))
));
return result;
}
}
You can create a new observable, and fire the event according to the access
level.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
// get route to be activated
this.routeToActivate = route.routeConfig.path;
// get user access levels
return new Observable(subscriber=>{
this._firebase.isUserAdmin
.map(user => user.access_level)
.subscribe(access => {
// Return an observable!
// Change your logic here...
return access === XXX ? subscriber.next(true) : subscriber.next(false);
}, err => subscriber.error());
})
}
Reference: https://rxjs-dev.firebaseapp.com/guide/observable