Search code examples
rxjsangular6angularfire5

Angular & RXJS - [ts] Property 'map' does not exist on type 'Observable<User>'


Since creating a new angular 6 project, some previous code that I've copied over doesn't seem to be working. This primarily seems to be rxjs syntax

On the .map, it displays the error:

[ts] Property 'map' does not exist on type 'Observable'<User>'.

I seem to be getting a similar error on another file with .take

Is anyone able to point me in the right direction to resolve this please?

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';

import { Observable } from 'rxjs';
import { AngularFireAuth } from 'angularfire2/auth';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/do';

@Injectable()

export class LoginGuardService implements CanActivate {

  constructor(
    private router: Router,
    private auth: AngularFireAuth
  ) { }


  canActivate(): Observable<boolean> {
    return this.auth.authState.map(authState => {
      if (authState) this.router.navigate(['/folders']);
      return !authState;
    }).take(1);
  }

}

Second Guard

canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):

Observable<boolean> {

    this.authGuardStateURL = state.url;

    return this.auth.authState.pipe( 
      take(1)
      .map(authState => !!authState)
      .do(auth => !auth ? this.router.navigate(['/login']) : true)
    )

  }

Solution

  • I reckon you used Angular CLI to create your app. Angular 6 comes with RxJS 6 and since v5, RxJS has been using pipeable operators.

    So your code should look like this:

    import { Injectable } from '@angular/core';
    import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';
    import { Observable } from 'rxjs';
    import { AngularFireAuth } from 'angularfire2/auth';
    import { map, take, tap } from 'rxjs/operators';
    
    @Injectable()
    
    export class LoginGuardService implements CanActivate {
    
      constructor(
        private router: Router,
        private auth: AngularFireAuth
      ) { }
    
      canActivate(): Observable<boolean> {
        return this.auth.authState.pipe(
          map(authState => {
            if (authState) this.router.navigate(['/folders']);
            return !authState;
          }),
          take(1)
        )
      }
    
      //Second Guard
    
      canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot): Observable<boolean> {
    
          this.authGuardStateURL = state.url;
    
          return this.auth.authState.pipe(
            take(1),
            map(authState => !!authState),
            tap(auth => !auth ? this.router.navigate(['/login']) : true)
          )
       }
    }
    

    Notice how you import the operators now and how you put map and take inside pipe method.