Angular 角度变量未定义
我编写了以下代码: authentication.service.tsAngular 角度变量未定义,angular,typescript,Angular,Typescript,我编写了以下代码: 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 : Us
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);
}
}
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']);
}
}
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())
}
}
user.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);
}
}
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']);
}
}
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())
}
}
导出类用户服务{
私有API_URL=environment.API_URL;
构造函数(私有http:HttpClient){}
getUsers(页码:number=1){
返回this.http.get(this.API_URL+'users/'{
params:new-HttpParams().set(“page”,page.toString())
});
}
寄存器(数据:用户){
返回this.http.post(this.API_URL+'users/',数据)
}
getUser(id:number){
返回this.http.get(this.API_URL+'users/'+id.toString())
}
}
登录getUser
-函数时调用,但当我检查控制台时,navbar构造函数给出错误,即authentication.service.ts
中的isStaff
-函数中的this.user
未定义。用户端点工作正常,因为当我在subscribe函数中记录data.results[0]
的值时,它会显示用户的数据
如何解决此问题?不太确定,但此代码对我来说毫无意义:
this.authService.isStaff()
您似乎正在调用一个服务,该服务将检查此.user,无论它是否已定义,这不是一个好主意
相反,您不应该使用该服务获取用户,然后将this.user
传递到导航栏组件中,然后直接检查是否this.user.is_staff
只是一个想法。这是因为变量
未定义
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;
只有在登录
服务和获取用户数据
完成后,才会定义this.user。在那之前没有。但是我认为Navbar
组件甚至在服务调用完成之前就已经初始化了
在上面的代码中,我没有看到对AuthenticationService.login
函数的任何调用。所以我有两个选择
选项1->在用户登录之前,不要显示navbar
组件
选项2->用户登录后,从AuthenticationService
抛出事件。在访问this.user之前,在navbar
组件中订阅该事件。我认为这是由于同步性。函数在值发出之前被调用。尝试转换逻辑相关的观察值toPromise()
,然后调用私有函数。您可能还想加入一些async/await
。@jamesmalred您有这样的例子吗?从您的代码中不清楚babar是在用户登录之后还是之前创建的。试着创建一个stackblitz演示。这不是意味着当我需要用户变量时,我需要反复调用它吗?我不是一个专家,但我认为一般来说,你登录,然后将登录信息保存到内存或会话存储或本地存储,所以你不必每次更改页面时都重新登录。将用户信息保存到对象后,应该能够将该对象传递到导航栏中。但是你的导航栏本身不应该调用你的服务。即使用户登录到控制台,仍然会抛出相同的错误。表示变量仍然未定义您是否表示只有在完成对login和this.userService.getUser的调用后才初始化navbar组件?如果是,您是否检查了从this.userService.getUser收到的响应?看起来您正在将其分配给此.user。