在创建方法之前等待ngInit

时间:2020-05-30 17:04:29

标签: angular rxjs

我想使用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,
      }
    );
  }
}

我可以将其合并吗?

1 个答案:

答案 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)重试请求。