1

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

  }
  • 2
    In RxJS 6 can't use the "patch" style of operators. You can install `rxjs-compat` package (https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md#backwards-compatibility) or even better update your code for RxJS 6. https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md – martin Jul 09 '18 at 11:33

1 Answers1

0

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.

codeepic
  • 3,723
  • 7
  • 36
  • 57
  • What an awesome accurate answer. Thank you a ton. There's a second guard I have in my question (sorry I was adding whilst you responded)...I was in the process of adding the pipe, but the .map errors with: Property 'map' does not exist on type 'MonoTypeOperatorFunction<{}>'. Any ideas? Thanks again. Much appreciated. –  Jul 09 '18 at 11:49
  • 1
    Yes, I get you, you get this error, because you are using `.map()` inside `pipe`. The dot makes a difference. `Pipe` takes rxjs operators as arguments, so you don't have to use the dot. The first argument/function takes observable, manipulates it and returns the output as input to the next argument/function inside `pipe`. I updated my answer with the code for second guard. `do` has been replaced by `tap` method. – codeepic Jul 09 '18 at 11:54