2016-10-08 20 views
17

Próbuję zwrócić obserwowalne, gdy otrzymam określoną wartość w subskrybenta, ale niestety nie.Powrót do obserwowania z subskrypcji

Jest to kod:

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

Nie ma zbyt wielu zasobów na obserwabli w kątowej 2, więc nie wiem od czego zacząć. Czy ktoś może w tym pomóc?

UPDATE -> Wersja robocza

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

Powinieneś googlowania obserwabli w ** rxjs ** zamiast NG2. jest mnóstwo zasobów. – drewmoore

+0

Dziękuję! Próbowałem tego, ale nie są one w tym samym formacie, w jakim Angular 2 je używa. Chyba będę musiał się tego nauczyć od zera. –

+0

Czy możesz wyjaśnić kontekst tego kodu? Ponieważ 'subscribe' zwraca obiekt' Subscription', aby zrezygnować z subskrypcji, a zatem nie można go przeciągnąć, zazwyczaj chcesz zrobić 'obserwowalny.subscribe (...); return obserservable'. – estus

Odpowiedz

31

Nie można powrócić zauważalny od subskrybować ale jeśli używasz map zamiast subscribe wtedy Observable jest zwracana.

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

Cześć, dziękuję za odpowiedź! Muszę wykonać pewne przetwarzanie wewnątrz subskrybowania w zależności od wartości, a następnie zwrócić true | false –

+0

Możesz to zrobić również w 'map', po prostu zmień' user.access_level' na '{user.access_level; ...} 'i możesz dodać wiele instrukcji, jak w normalnej funkcji. Upewnij się, że zwrócisz wynik na końcu, bo inaczej odbiorca niczego nie odbierze. –

+0

Próbowałem za pomocą tego: 'powrócić this._firebase.isUserAdmin .map (user => { niech AccessLevel = user.access_level; if (AccessLevel === 'admin') { return true;} }). first(); ' , ale nie odblokowuje widoku, więc domyślam się, że nie zwraca tego prawdziwego oświadczenia. –

2

Możemy konwertować obserwowalnym obiekt obiecać użyciu toPromise metody. więc kod może być realizowane następująco:

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

Nie trzeba mapę, kod poniżej określa predykatu i funkcji rzutowania na pierwsze.

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