我想使用this.user
变量,但不幸的是,我必须在ngOnInit
方法中使用observable来获取它们,因此当我尝试访问this.user.username
时,它显示为undefined,因为它没有没有加载。
@Injectable({ providedIn: 'root' })
export class SettingsService implements OnInit {
user: User | null = null;
userSubscription: Subscription;
constructor(
private http: HttpClient,
private authService: AuthenticationService
) {}
ngOnInit(): void {
this.userSubscription = this.authService.getUser().subscribe((user) => {
if (user !== null) {
this.user = user;
return;
}
});
}
changeUsername(username: string): Observable<{ message: string }> {
console.log(username);
console.log(this.user.username);
return this.http.post<{ message: string }>(
`${environment.apiUri}/users/${this.user.username}/username`,
{
username,
}
);
}
}
我可以将其合并吗?
答案 0 :(得分:1)
您也可以使this.user
成为RxJS BehaviorSubject
。因此,现在您可以将user
推到可观察的位置,并且可以在changeUsername
函数中收听它。然后,可以使用switchMap
运算符将user
的值映射到HTTP请求。请注意,如果user
的值仍为null
,我们将返回RxJS EMPTY
而不是请求。尝试以下
import { BehaviorSubject, EMPTY, Observable } import 'rxjs';
import { switchMap, take } import 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class SettingsService implements OnInit {
user = new BehaviorSubject<User | null>(null);
userSubscription: Subscription;
constructor(
private http: HttpClient,
private authService: AuthenticationService
) {}
ngOnInit(): void {
this.userSubscription = this.authService.getUser().subscribe((user) => {
if (user !== null) {
this.user.next(user); // <-- push it to the observable
// `return` isn't required here
}
});
}
changeUsername(username: string): Observable<{ message: string }> {
console.log(username);
return this.user.pipe(
take(1),
switchMap(user => {
console.log(user.username);
if (user) {
return this.http.post<{ message: string }>(`${environment.apiUri}/users/${this.user.username}/username`, { username });
} else {
return EMPTY;
}
});
);
}
}
您仍然可以像以前一样订阅changeUsername
函数。唯一不同的是,仅当this.user
变量不是null
时才进行调用。您还可以返回错误(例如,使用throwError
)而不是EMPTY
,并在一段时间后使用retryWhen
运算符(例如,使用timer
)重试请求。