我编写了以下代码:
authentication.service.ts
export class AuthenticationService {
private readonly ACCESS_TOKEN = 'ACCESS_TOKEN';
private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
private loggedUser: string;
public userId : number;
public user : User;
private API_URL= environment.API_URL;
constructor(private http: HttpClient, private router:Router, private userService : UserService) {}
login(username: string, password:string): Observable<boolean> {
return this.http.post<any>(this.API_URL + 'token/', { username: username, password: password })
.pipe(
tap(tokens => this.doLoginUser(username, tokens)),
mapTo(true),
catchError(error => {
return of(false);
}));
}
logout() {
this.doLogoutUser();
}
decodeJwt(token){
let decoded = jwt_decode(token);
this.userId = decoded.user_id;
}
isLoggedIn() {
return !!this.getAccessToken();
}
isStaff() {
return this.user.is_staff;
}
refreshToken() {
return this.http.post<any>(this.API_URL + "token/refresh/", {
'refresh': this.getRefreshToken()
}).pipe(
tap((tokens: Tokens) => {
this.storeJwtToken(tokens.access);
}),
mapTo(true),
catchError(error => {
this.doLogoutUser();
this.router.navigate(["/login"])
return of(false);
}
)
);
}
getAccessToken() {
return localStorage.getItem(this.ACCESS_TOKEN);
}
getUserData(){
this.userService.getUser(this.userId).subscribe(data => {
this.user = data.results[0]
console.log(this.user)
})
}
private doLoginUser(username: string, tokens: Tokens) {
this.loggedUser = username;
this.storeTokens(tokens);
this.decodeJwt(tokens.access);
this.getUserData();
}
private doLogoutUser() {
this.loggedUser = null;
this.removeTokens();
}
private getRefreshToken() {
return localStorage.getItem(this.REFRESH_TOKEN);
}
private storeJwtToken(accessToken: string) {
localStorage.setItem(this.ACCESS_TOKEN, accessToken);
}
private storeTokens(tokens: Tokens) {
localStorage.setItem(this.ACCESS_TOKEN, tokens.access);
localStorage.setItem(this.REFRESH_TOKEN, tokens.refresh);
}
private removeTokens() {
localStorage.removeItem(this.ACCESS_TOKEN);
localStorage.removeItem(this.REFRESH_TOKEN);
}
}
navbar.component.ts
export class NavbarComponent implements OnInit {
constructor(public authService : AuthenticationService, private router : Router) {
}
ngOnInit(): void {
console.log(this.authService.isStaff())
}
logOut(){
this.authService.logout()
this.router.navigate(['/login']);
}
}
user.service.ts
export class UserService {
private API_URL= environment.API_URL;
constructor(private http : HttpClient) { }
getUsers(page:number=1){
return this.http.get<any>(this.API_URL + 'users/', {
params: new HttpParams().set("page", page.toString())
});
}
register(data:User) {
return this.http.post<any>(this.API_URL + 'users/', data)
}
getUser(id : number){
return this.http.get<any>(this.API_URL + 'users/' + id.toString())
}
}
在登录getUser
函数时调用了该函数,但是当我检查控制台时,导航栏构造函数给出了一个错误,即this.user
函数中的isStaff
在authentication.service.ts
中未定义。用户端点正常工作,因为当我在订阅功能中控制台记录data.results[0]
的值时,它将显示用户的数据。
我该如何解决这个问题?
答案 0 :(得分:1)
那是因为变量是undefined
。
export class AuthenticationService {
private readonly ACCESS_TOKEN = 'ACCESS_TOKEN';
private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
private loggedUser: string;
public userId : number;
public user : User; =======> UNDEFINED
private API_URL= environment.API_URL;
仅在login
服务且getUserData
完成之后才定义this.user。在那之前。但是我认为Navbar
组件甚至在服务调用完成之前就已初始化。
在上面的代码中,我看不到对AuthenticationService.login
函数的任何调用。所以我看到2个选项,
选项1->在用户登录之前,不显示navbar
组件。
选项2->一旦用户登录,就会从AuthenticationService
引发事件。在访问this.user之前,请在navbar
组件中订阅该事件。
答案 1 :(得分:0)
不确定,但是此代码对我而言没有意义:this.authService.isStaff()
您似乎正在调用一项服务,该服务将检查this.user(是否已定义),这不是一个好主意。
相反,您不应该使用该服务来获取用户,然后将this.user
传递到导航栏组件中,然后直接检查是否this.user.is_staff
吗?
一个想法。