【问题标题】:Uncaught (in promise): TypeError: this.auth.user$.map is not a functionUncaught (in promise): TypeError: this.auth.user$.map is not a function
【发布时间】:2018-11-15 21:55:37
【问题描述】:

我是 Angular 的新手,在进行开发时,以下代码工作正常(我使用 Visual Studio Code 作为代码编辑器)

当我点击下面的菜单链接时,控制台窗口中发生错误

ng-version="6.0.9"

npm list --depth=0 
+-- rxjs@6.2.2
+-- rxjs-compat@6.2.2

ERROR Error: Uncaught (in promise): TypeError: this.auth.user$.map is not a function
TypeError: this.auth.user$.map is not a function
    at AuthGuard.push../src/app/auth-guard.service.ts.AuthGuard.canActivate (auth-guard.service.ts:22)
    at MapSubscriber.project (router.js:2768)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:35)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at Observable._subscribe (subscribeToArray.js:5)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:42)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:28)
    at MapOperator.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call (map.js:18)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:23)
    at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (mergeMap.js:28)
    at AuthGuard.push../src/app/auth-guard.service.ts.AuthGuard.canActivate (auth-guard.service.ts:22)
    at MapSubscriber.project (router.js:2768)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:35)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at Observable._subscribe (subscribeToArray.js:5)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:42)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:28)
    at MapOperator.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call (map.js:18)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:23)
    at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (mergeMap.js:28)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:3751)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1540)

代码出现错误:auth-guard.service.ts

import { Injectable } from '@angular/core';
import { CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';
import { Observable } from "rxjs/Rx";
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

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

  canActivate(route, state: RouterStateSnapshot) {
    return this.auth.user$.map(user => {
      if (user) return true; 

      this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
      return false;
    });
  }

}

auth.service.ts 代码

import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase';
import { Observable } from 'rxjs';
import { ActivatedRoute } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  user$: Observable<firebase.User>;

  constructor(private afFireAuth: AngularFireAuth,private route: ActivatedRoute) {
    this.user$ = afFireAuth.authState;
  }

  login(){
    let returnUrl = this.route.snapshot.queryParamMap.get('returnUrl') || '/';
    localStorage.setItem('returnUrl', returnUrl);


    this.afFireAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider);
  }

  logout() {

    this.afFireAuth.auth.signOut();
  }

}

我期待所有专家的解决方案

【问题讨论】:

  • 您的应用使用哪个版本的 rxjs?
  • 您可能应该粘贴您的auth.service 代码。它的user$ 值没有map 函数,这可能表明auth 服务没有正确生成users$ 成员。
  • @Sergeon 已经为您指明了正确的方向。但是让我问一下canActivate 应该做什么;你为什么使用map
  • @FK82 据我所知 canActivate 用于在 app.module.ts RouterModule.forRoot 部分 { path: 'my/orders', component: MyOrdersComponent, canActivate: [AuthGuard] }, 中为登录用户显示一些链接示例
  • @rduncan 添加到原始代码中的所有版本

标签: javascript typescript angular6


【解决方案1】:

问题是由于 Angular 6 上的 ma​​p 语法的较新版本。您需要更改 import 语句并将 .pipe 与 Angular 6 版本中的地图一起使用。

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { map } from 'rxjs/operators';

@Injectable()
export class AuthGuard implements CanActivate{

  constructor(private auth: AuthService, private router: Router) { }
  canActivate() {
     return this.auth.user$.pipe(map (
       user => {
      if ( user ) return true;

      this.router.navigate(['/login']);
      return false;
    }
    ));
  }
}

【讨论】:

    【解决方案2】:

    auth-guard.service.ts 需要改为

    import { Injectable } from '@angular/core';
    import { CanActivate, Router, RouterStateSnapshot } from '@angular/router';
    import { AuthService } from './auth.service';
    
    //import { Observable } from "rxjs/Rx";
    //import { map } from 'rxjs/operators';
    
    import 'rxjs/add/operator/map'; 
    
    ....
    export class AuthService {
     ....
    }
    

    【讨论】:

    • @VijayDhanvai 我已经将一个解决方案标记为答案,它对我有用
    【解决方案3】:
    import { Injectable } from '@angular/core';
    import { CanActivate } from '@angular/router';
    import { AuthService } from './auth.service';
    import { Router } from '@angular/router';
    import { map } from 'rxjs/operators';
    @Injectable({
      providedIn: 'root'
    })
    export class AuthGuardService implements CanActivate{
    
      constructor(private auth : AuthService,private router : Router) { }
    
      canActivate(){
        return this.auth.user$.pipe(map(user=>{
          if(user){
            return true;
          }
          else {
            this.router.navigate(['/login']);
            return false;
          }
        }));
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-04-13
      • 2020-03-17
      • 2020-01-06
      • 2021-03-10
      • 2021-09-30
      • 2020-12-22
      • 2019-06-15
      • 2017-07-20
      • 1970-01-01
      相关资源
      最近更新 更多