2016-10-08 12 views
17

サブスクライバで特定の値を取得したときに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で観測ではありませんので、私はどこから始めれば分かりません。誰か助けてくれますか?

UPDATE - >ワーキングバージョン

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

。たくさんのリソースがあります – drewmoore

+0

ありがとう!私はそれを試みたが、Angular 2が同じフォーマットで来ない。私はそれを最初から学ばなければならないと思う。 –

+0

このコードのコンテキストをさらに説明できますか? 'subscribe'は' Subscription'オブジェクトを返すので、それをチェーン解除することはできません。一般的に 'observable.subscribe(...); 「観察可能」に戻る。 – estus

答えて

31

あなたは、サブスクライブから、観察を返すことはできませんが、あなたが、その後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; 
} 
+0

こんにちは、答えをありがとう!値に応じてsubscribe内で何らかの処理を行い、true | falseを返す必要があります。 –

+0

'map'でも同様に' user.access_level'を '{user.access_level; ...} 'そして、通常の関数のように複数の文を追加することができます。最後に結果を返すようにしてください。そうしないと、受信者は何も受信しません。私はこれを使用してみました –

+0

: '戻りthis._firebase.isUserAdmin .MAP(ユーザー=> { ACCESSLEVEL = user.access_levelを聞かせて、 IF(ACCESSLEVEL === '管理'){ リターン真;} })。first(); ' 私はそれが本当のステートメントを返さないと思うので、それはビューのロックを解除しません。 –

2

我々はtoPromiseメソッドを使用して約束する観察可能なオブジェクトに変換することができます。以下のように ので、コードを実装することができます。

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

あなたがマップを必要としない、以下のコードは、最初のための述語と投影機能を指定します。あなたは** rxjs **なく、NG2で観測をグーグルでされなければならない

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

関連する問題