Pippy Longstocking
Pippy Longstocking

Reputation: 303

Upgraded to Angular/AngularCLI/Rxjs version 6 but getting "Property 'take' does not exist on type 'Observable"

I decided to upgrade my Angular5 working project to Angular6 and along that, upgraded all dependencies (for example rxjs is now at version 6 as well as the angular-cli)

I am having an issue that I cannot seem to fix:

ERROR in src/app/services/auth/auth-guard.service.ts(25,14): error TS2339: Property 'take' does not exist on type 'Observable<User>'.

This was not an issue before. I understand that now we need to wrap rxjs operators with 'pipe' and although I tried that here the embedded code inside the pipe wrapper would still cause similar issues so I decided to put the broken class here instead:

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

import { AuthService } from './auth.service';

@Injectable()
export class AuthGuardService implements CanActivate {

    constructor(
        private authService: AuthService,
        private router: Router
    ) { }

    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<boolean> | Promise<boolean> | boolean {
        return this.authService.currentUser
            .take(1)
            .map(user => !!user)
            .do(signedIn => {
                if (!signedIn) {
                    console.log('access denied');
                    this.router.navigate(['/signin']);
                }
            });
    }

}

I tried fixing it with:

import { take } from 'rxjs/operators';

...

return this.authService.currentUser
    .pipe(
        take(1)
            .map(user => !!user)
            .do(signedIn => {
                if (!signedIn) {
                    console.log('access denied');
                    this.router.navigate(['/signin']);
                }
            })
    );

But then got "map does not exist" and so forth. If I take(1).pipe( then I get pipe does not exist.

I am not having success getting this to work of finding an appropriate answer.

Just in case setting of this.authService.currentUser in AuthService looks like this (notice that for this one I successfully used the pipe to get switchMap to work):

constructor(
        private router: Router,
        private afAuth: AngularFireAuth,
        private afs: AngularFirestore,
        private http: HttpClient,
        private headerService: HeaderService
    ) {
        this.authState = this.afAuth.authState;
        this.currentUser = this.afAuth.authState
            .pipe(
                switchMap(user => {
                    if (user) {
                        return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
                    } else {
                        return of(null);
                    }
                })
            );
    }

Upvotes: 2

Views: 635

Answers (1)

Sachila Ranawaka
Sachila Ranawaka

Reputation: 41417

when you are using pipeable operators, you need to import all the operators you use. Also, dot notation is not required inside the pipe function.

import { take,map,tap } from 'rxjs/operators';

...

return this.authService.currentUser
    .pipe(
        take(1),
        map(user => !!user),
        tap(signedIn => {
                if (!signedIn) {
                    console.log('access denied');
                    this.router.navigate(['/signin']);
                }
            })
    );

Upvotes: 3

Related Questions