我在这里迷失了方向,我试图在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
});
答案 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