在角度6中发布服务功能内的赋值问题

时间:2018-08-02 18:18:19

标签: angular

我在这里迷失了方向,我试图在Service内部的函数中为变量分配一个值,但我不明白是什么问题。从订阅内部看,它似乎可以正常工作,但是当我尝试调用它时,undefined

我试图为该变量赋值:private userInfo: any函数内部的autoAuthUser()

有趣的是,如果我从注销功能中console.log userInfo,它显示的是值

这是我的服务

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Subject } from "rxjs";
import { Router } from "@angular/router";
import { SignUpData } from "../models/sign-up.model";
import { LogInData } from "../models/log-in.model";
import { User } from "../models/user";
import { computeStyle } from "../../../node_modules/@angular/animations/browser/src/util";
import { TouchSequence } from "../../../node_modules/@types/selenium-webdriver";


@Injectable({ providedIn: "root" })
export class AuthService {
    private isAuthenticated = false
    private token: string
    private authStatusListner = new Subject<boolean>()
    private tokenTimer: any
    private isAdmin: boolean
    private userInfo: any


    signupUrl = "http://localhost:3000/signup";
    loginUrl = "http://localhost:3000/login"

    constructor(private http: HttpClient,
        private router: Router) { }


    getToken() {
        return this.token
    }

    checkIfAdmin() {
        return this.isAdmin
    }


    getAuthStatus() {
        return this.isAuthenticated

    }

    getAuthStatusListner() {
          return this.authStatusListner.asObservable()    
    }

    // Cheacking if the user have the login token in the local storage for autoLogin and the exparation date 
    autoAuthUser() {
        const AuthInformation = this.getAuthData()
        if (!AuthInformation) {
            return
        }
        const now = new Date();
        const expairesIn = AuthInformation.expirationDate.getTime() - now.getTime();
        if (expairesIn > 0) {
            this.token = AuthInformation.token
            this.setAuthTimer(expairesIn / 1000)
            this.autoLogin().subscribe(user => {
                this.userInfo = user
                console.log(this.userInfo)
            })
            this.authStatusListner.next(true)
            this.isAuthenticated = true
        }
    }


    getUserInfo() {
        if (this.token) {
            console.log(this.userInfo)
            return this.userInfo
        }
    }


    createUser(name: string, email: string, password: string) {
        const authData: SignUpData = { name: name, email: email, password: password }
        this.http.post(this.signupUrl, authData)
            .subscribe(response => {
            });
    }


    autoLogin() {
        return this.http.get<{ user: any }>(this.loginUrl)
    }



    login(email: string, password) {
        const authData: LogInData = { email: email, password: password }
        this.http.post<{ token: string, expiresIn: number, isAdmin: boolean, user: any }>(this.loginUrl, authData)
            .subscribe(response => {
                const token = response.token
                this.token = token;
                if (token) {
                    if (response.isAdmin) {
                        this.isAdmin = response.isAdmin
                    }
                    this.userInfo = response.user
                    const expiersInDuration = response.expiresIn
                    this.setAuthTimer(expiersInDuration)
                    this.isAuthenticated = true
                    this.authStatusListner.next(true);
                    const now = new Date;
                    const expirationDate = new Date(now.getTime() + expiersInDuration * 1000)
                    this.saveAuthData(token, expirationDate)
                    this.router.navigate(['/user'])
                }
            });
    }


    // User logout
    logout() {
        this.token = null
        this.isAuthenticated = false
        this.isAdmin = false
        this.authStatusListner.next(false)
        clearTimeout(this.tokenTimer)
        this.clearAuthData()
        this.router.navigate(['/user'])
        console.log(this.userInfo)

    }


    // Setting the timer for the token expiration
    private setAuthTimer(duration: number) {
        this.tokenTimer = setTimeout(() => {
            this.logout();
        }, duration * 1000)
    }

    // Setting the Auth token in the local storage
    private saveAuthData(token: string, expirationDate: Date) {
        localStorage.setItem("token", token)
        localStorage.setItem("expiration", expirationDate.toISOString())

    }

    // Clearing the token from local storage in logout
    private clearAuthData() {
        localStorage.removeItem('token')
        localStorage.removeItem('expiration')
    }

    // Geting the login token if it exist in the user local storage
    private getAuthData() {

        const token = localStorage.getItem("token");
        const expirationDate = localStorage.getItem("expiration")
        if (!token || !expirationDate) {
            return
        }
        return {
            token: token,
            expirationDate: new Date(expirationDate)

        }
    }


    // ******* Loading the token from local storage in the app component
}

[编辑]

调用组件中的服务功能

应用程序组件:

import { Component, OnInit } from '@angular/core';
import { AuthService } from './services/auth.service';


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

constructor(private authService: AuthService){}

  ngOnInit(){
    this.authService.autoAuthUser()
  }
}

标题组件:

import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { Movies } from '../models/movies.model';
import { MoviesService } from '../services/movies.service';
import { FilterPipe } from 'ngx-filter-pipe';
import { DomSanitizer } from '@angular/platform-browser';
import { AuthService } from '../services/auth.service';
import { FormControl, Validators, NgForm, FormGroup } from '@angular/forms';
import { Subscription } from 'rxjs';
import { ModalDirective } from "angular-bootstrap-md";
import { User } from '../models/user';


@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css'],

})
export class HeaderComponent implements OnInit, OnDestroy {
  @ViewChild('signUpModal') signUpModal: ModalDirective;
  @ViewChild('logInModal') logInModal: ModalDirective;

  //Admincheck
  isAdmin = false


  userData: any
  //Spinners
  loginSpinner = false
  signUpSpinner = false
  //Authintications cheack
  userIsAuthinticated = false

  //Movies array for the search
  movies: Movies[]

  //Login Form
  loginForm: FormGroup

  //SignUp form
  signUpForm: FormGroup

  private authListnerSubs: Subscription;

  constructor(private movieService: MoviesService,
    private filterPipe: FilterPipe,
    public sanitizer: DomSanitizer,
    private authService: AuthService) { }

    sanitize(url: string) {
    return this.sanitizer.bypassSecurityTrustUrl('http://localhost:3000/' + url);
  }


  ngOnInit() {

    this.isAdmin = this.authService.checkIfAdmin()
    this.movieService.getAllMovies()
      .subscribe(
        (movies: Movies[]) => (this.movies = movies)

      )
    this.userData = this.authService.getUserInfo()
    this.userIsAuthinticated = this.authService.getAuthStatus()   
    this.authService.getUserInfo()

    this.authListnerSubs = this.authService.getAuthStatusListner()
      .subscribe(isAuthonticated => {
        this.userIsAuthinticated = isAuthonticated
        if(this.userIsAuthinticated){
         console.log(this.userData)
          this.loginSpinner = false
          this.logInModal.hide();
          this.loginForm.reset()

        }
          this.loginSpinner = false

      });

1 个答案:

答案 0 :(得分:0)

Suresh在注释中正确指出了您的问题,您在autoAuthUser中向AppComponent发送了异步呼叫,在此之前,您正在向{{1 }}中的getUserInfo中。您已经具备了完成这项工作的全部能力,只需要重新排列代码即可。

HeaderComponent的回调中移动this.authStatusListner.next(true)

autoLogin

autoAuthUser() { const AuthInformation = this.getAuthData() if (!AuthInformation) { return } const now = new Date(); const expairesIn = AuthInformation.expirationDate.getTime() - now.getTime(); if (expairesIn > 0) { this.token = AuthInformation.token this.setAuthTimer(expairesIn / 1000) this.autoLogin().subscribe(user => { this.userInfo = user console.log(this.userInfo) this.authStatusListner.next(true) }) this.isAuthenticated = true } } 返回之前,不要致电getUserInfo

getAuthStatusListener