首页 > 解决方案 > 用户登录时更新所有用户相关数据(可观察)

问题描述

我正在开发一个带有身份验证的角度应用程序。该应用程序有一个仪表板,显示登录用户的用户名。问题是,当您使用新用户登录时,它仍然显示上次登录用户的用户名。

所以当用户登录时它不会更新用户名(可观察的)。我认为问题是我在方法中获取了用户名ngOnInit

如何更新所有用户相关数据?

header.component.ts(应显示用户名)

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../../core/auth.service';
import { Apollo } from 'apollo-angular';
import gpl from 'graphql-tag';

const registeredUser = gpl`
  query registeredUser {
    registeredUser {
      name
    }   
  }
`

@Component({
  selector: 'dashboard-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  private user$;

  constructor(
    private authService : AuthService,
    private apollo : Apollo) { }

  ngOnInit() {
    this.user$ = this.apollo.watchQuery<any>({
      query: registeredUser
    })
      .valueChanges;
  }

  logout() {
    this.authService.logout();
  }

}

身份验证服务

import { Injectable } from '@angular/core';

import { JwtHelper } from 'angular2-jwt';
import { Apollo } from 'apollo-angular';
import gpl from 'graphql-tag';
import { Router } from '@angular/router';

const register = gpl`
mutation($name: String!, $email_mobile: String!, $password: String!) {
  register(name: $name, email_mobile: $email_mobile, password: $password) {
    success
    token
    user {
      name
      email
      mobile
    }
    errors {
      message
      key
    }
  }
}
`;

const login = gpl`
mutation($email_mobile: String!, $password: String!) {
  login(email_mobile: $email_mobile, password: $password) {
    success
    token
    user {
      name
      email
      mobile
    }
    errors {
      message
      key
    }
  }
}
`;

@Injectable()
export class AuthService {
  
  constructor(
    private jwtHelper: JwtHelper,
    private apollo: Apollo,
    private router: Router) { }


  isLoggedIn(): boolean {
    const token = localStorage.getItem('token');

    if(!token)
      return false;

    // Check whether the token is expired and return
    // true or false
    return !this.jwtHelper.isTokenExpired(token);
  }

  async register(name: string, email_mobile: string, password: string) {

    let regInfo = {};

    await this.apollo.mutate({
      mutation: register,
      variables: {
        name,
        email_mobile,
        password
      }
    }).subscribe(({data}) => {
      
      const regData = data.register;

      if(regData.success) {
        // set token to Local Storage
        localStorage.setItem("token", regData.token);
        this.router.navigate(['/dashboard']);
      } else {
        regInfo["errors"] = regData.errors;
      }
      regInfo["success"] = regData.success;
    });

    return regInfo;
  }

  async login(email_mobile: string, password: string) {
    let regInfo = {};

    await this.apollo.mutate({
      mutation: login,
      variables: {
        email_mobile,
        password
      }
    }).subscribe(({data}) => {

      const regData = data.login;
      if(regData.success) {
        // set token to Local Storage
        localStorage.setItem("token", regData.token);
        regInfo["user"] = regData.user;
        this.router.navigate(['/dashboard']);
      } else {
        regInfo["errors"] = regData.errors;
      }
      regInfo["success"] = regData.success;
    });

    return regInfo;
  }

  logout(){
    localStorage.removeItem("token");
  }
}

标签: javascriptnode.jsangularobservable

解决方案


您应该订阅 Apollo 课程中的更改,而不仅仅是取消它们。当另一个用户飞过时,您的代码会检索变量,但不会留在管道上监听。

你的代码

this.user$ = this.apollo.watchQuery<any>({
      query: registeredUser
    })
      .valueChanges;

我的设想

this.apollo.valueChanges.subscribe(
      ({ data }) => {
        this.user$ = [...data.user];
      }
    );

记住孩子们,请取消订阅您的管道!

在此处阅读有关 GraphQL 订阅的更多信息!

https://alligator.io/angular/graphql-subscriptions/


推荐阅读