如何从subscribe返回observable

时间:2016-10-08 18:14:31

标签: angular typescript rxjs observable

当我在订阅者中获得某个值时,我正在尝试返回一个observable,但我失败了。

这是代码:

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
        });
}

角度2中的可观察量资源不多,所以我不知道从哪里开始。有人可以帮忙吗?

更新 - &gt;工作版

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();
        }

6 个答案:

答案 0 :(得分:68)

您无法从订阅中返回可观察对象,但如果您使用map而不是subscribe,则会返回Observable

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;
}

答案 1 :(得分:4)

我们不能只将pipe中的mapimport { 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;
  }
}

答案 2 :(得分:2)

我们可以使用toPromise方法将Observable对象转换为promise。 所以代码可以按照以下方式实现:

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();
    }

答案 3 :(得分:1)

您不需要地图,下面的代码首先指定谓词和投影函数。

RIGHT("00" + (DT_WSTR,10)(DATEDIFF("ss",@[User::StartDate],@[User::EndDate]) / 3600),2) + ":" +
RIGHT("00" + (DT_WSTR,10)((DATEDIFF("ss",@[User::StartDate],@[User::EndDate]) % 3600) / 60)   ,2) + ":" + 
RIGHT("00" + (DT_WSTR,10)(DATEDIFF("ss",@[User::StartDate],@[User::EndDate])% 60),2)

More on first

答案 4 :(得分:1)

如果要订阅可观察的对象,请执行此操作,处理结果,然后在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;
}

答案 5 :(得分:-1)

您可以创建一个新的可观察对象,并根据access级别触发事件。

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());
    })
}

参考:https://rxjs-dev.firebaseapp.com/guide/observable