【问题标题】:get user role from database based on user id in angular根据角度中的用户ID从数据库中获取用户角色
【发布时间】:2018-11-09 15:39:08
【问题描述】:

我正在使用“身份验证服务”来保留所有用户身份验证功能。当用户通过身份验证时,我得到用户的 id 并从数据库表中获取相关记录,但我无法获取“角色”字段的值。我在构造函数中使用的代码是这样的:

constructor(
    private _firebaseAuth: AngularFireAuth,
    private db: AngularFireDatabase,
    private router: Router) {
    this.user = _firebaseAuth.authState;

    this.user.subscribe(
        (user) => {
            if (user) {
                this.userDetails = user;

                this.userEmail = this.userDetails.email;
                this.uid = this.userDetails.uid;

                this.getUserRole(this.uid).subscribe(result => {
                    this.role = result.role;
                    console.log('role >>>>>>>>>>>>>', this.role);
                });

                console.log('uid >>>>>>>>>>>>>', this.uid);
                console.log('role >>>>>>>>>>>>>', this.role);
            }
            else {
                this.userDetails = null;
            }
        }
    );
}

getUserRole(userId: string): Observable<any> {
    return this.db.list('users', ref => ref.orderByChild('uid').equalTo(this.uid)).valueChanges()
        .map(result => result[0]);
}

this.uid 具有正确的值,但 this.role 未定义。

我认为对数据库表的调用是异步的问题。 我怎样才能得到这个值?

【问题讨论】:

  • 你试过this.currUser.subscribe(val =&gt; this.role = val[0].role) 吗?
  • 相同结果... this.rolesubscribe 之外未定义
  • 您应该等待订阅完成,否则您将永远无法定义它。
  • 喜欢这个? this.user.subscribe( val =&gt; this.role = val[0].role, () =&gt; ); '()=>' 后面应该是什么?

标签: angular firebase firebase-realtime-database angular5


【解决方案1】:

您不能在 .subscribe() 方法之外访问变量,请将其放在 subscribe 中

 this.currUser.subscribe(val => {
    this.role = val[0].role;
    console.log(this.role);
});

【讨论】:

  • 如果我把它放在订阅中,我该如何使用它?
  • 调用一个方法并在里面使用
  • 这是否应该获取 this.currUser 作为参数并返回一些东西?
  • 不只是调用whaterver方法newMethod(this.role);
  • this.role 在函数外不可见。问题是this.role 在订阅之外是不可见的
【解决方案2】:

我添加了一些代码让你理解 observable 的回调。看看吧。

this.currUser.subscribe(
        (val) => {
            // This is called as success callback
            this.role = val[0].role;
           // perform task using this.role. You should be writing your code here.
        },
        (error) => {
                // This is called as error callback, It will be executed if any erorrs were thrown from `currUser()`
                // log if there are any errors here
        },
        () => {
            // This is called as complete block
            // This will be executed after success callback or the error callback.
        }
);

更新:

this.user.subscribe(
    (user) => {
        if (user) {
            this.userDetails = user;

            this.userEmail = this.userDetails.email;
            this.uid = this.userDetails.uid;

            this.getUserRole(this.uid).subscribe(result => {
                this.role = result.role;
                console.log('role >>>>>>>>>>>>>', this.role);       // print log 1
            });

            // log 2 will be executed before log 1 this is due to asynchronous behaviour
            console.log('role >>>>>>>>>>>>>', this.role);           // print log 2
        }
        else {
            this.userDetails = null;
        }
    }
);

log 2 将在 log 1 之前执行,这是由于异步行为。如果您认为您的代码按行号顺序执行,那么您就错了。 getUserRole 是异步方法。

您也可以使用getset 从其他组件访问this.role。做什么都是合适的。

您应该做的是仅在未定义的情况下获取this.role

在您尝试访问this.role 的外部组件中,首先检查undefined,然后再访问它。

其他组件.ts

if(this.role != undefined){
 let role = this.role
}

演示: 查看here 了解异步方法的工作原理

【讨论】:

  • 我明白了结构应该是怎样的,但是我不明白应该在() =&gt; 中做什么。外部(val) =&gt; 变量this.role 仍未定义
  • 在执行成功块之前,您不能使用this.role。这是一个异步操作。您的 console.log(this.role) 外部订阅块将在您的成功块执行之前执行。这就是为什么你会变得不确定。
  • 我明白为什么我在console.log 中未定义。如果我将console.log 放在() =&gt; 中,则不会发生任何事情。这意味着subscribe 永远不会完成?有没有其他方法可以获取价值?
  • 在你的代码中你说console.log(this.role)在成功块内工作,现在你说什么也没发生。
  • console.log(this.role) 在成功块之外。在按照您的示例进行操作后,我放入了成功块,那时什么也没发生
【解决方案3】:

我在用户服务中创建了如下函数:

getUserRole(userId: string): Observable<any> {
    return this.db.list('users', ref => ref.orderByChild('uid').equalTo(userId)).valueChanges()
        .map(result => result[0]);
}

然后我在组件中获得了用户 ID:

get uid(): string {
    return this.authService.uid;
}
set uid(value: string) {
    this.authService.uid = value;
}

并在onNgInit()中调用函数:

ngOnInit() {
    if (this.uid != undefined) {
        let uid = this.uid;

        this.userService.getUserRole(this.uid).subscribe(result => {
                    this.role = result.role;
        });
    }
}

最后我在html模板中使用了*ngIf="role == '&lt;role&gt;'

【讨论】:

    猜你喜欢
    • 2014-10-22
    • 2019-06-16
    • 2014-08-19
    • 2018-08-20
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    相关资源
    最近更新 更多