首页 > 解决方案 > 我怎样才能在这个函数中提供一个 Observable?

问题描述

当我将一组凭据发布到我的 api 并取回我想要存储的数据时,应该在登录过程发生时出现以下错误。

错误:TypeError:您在预期流的位置提供了无效对象。您可以提供 Observable、Promise、Array 或 Iterable。

这是我的代码:我也试过而不是res['user_id']这个版本this.user['user_id'],但后来我得到一个错误,它无法读取 null 的 user_id。

首先我的服务发布凭据并负责存储:

user = null;
  refreshToken = null;
  private authenticationState = new BehaviorSubject(false);
  public authenticationState$ = this.authenticationState.asObservable();
...
checkToken() {
       this.storage.get(TOKEN_KEY).then(access => {
           if (access) {
               this.user = this.helper.decodeToken(access);
               this.authenticationState.next(true);
           }
           else {
            this.storage.get(REFRESH_TOKEN_KEY).then(reaccess => {
                this.user = this.helper.decodeToken(reaccess);
                this.authenticationState.next(true);
            });
           }
       });
   }

 apilogin(username: string, password: string) {
    return this.http.post<any>(`http://127.0.0.1:8000/api/token/`, { username, password })
    .pipe(
        switchMap((res: any) => {
            // run all in paralell
            return forkJoin(
                this.storage.set(TOKEN_KEY, res['access']),
                this.storage.set(USERNAME_KEY, username),
                this.storage.set(USER_ID, res['user_id']),
                this.user = this.helper.decodeToken(res['access'])
            );
          }),
    // now we know for sure storage values have been set,
    // therefore call checkToken()
        tap(() => this.checkToken()),
        catchError(e => {
            this.showAlert('Oops smth went wrong!');
            throw new Error(e);
        }));

}

apilogout() {
      this.storage.remove(USER_ID),
      this.storage.remove(REFRESH_TOKEN_KEY),
      this.storage.remove(USERNAME_KEY),
      this.storage.remove(TOKEN_KEY)
  }

这是我的登录页面。在这里我总是出错,这就是记录此错误的地方。

apiSubmit() {
  console.log('Hello World');
  this.submitted = true;

  // if form is invalid => stop
  if (this.loginForm.invalid) {
      return;
  }
  this.isLoading = true;
  this.loadingEl.present();
  this.authService.apilogin(
  this.f.username,
  this.f.password)
      .pipe(tap(x => this.loadingEl.dismiss()),
      )
      .subscribe(
        data => {
          console.log('0');
          this.router.navigate([this.returnUrl]);
        },
        error => {
          console.log('1');
          this.loadingEl.dismiss();
          this.error = error;
          console.log(error);
          this.isLoading = false;
        }
      );
}

标签: javascriptangulartypescriptionic-frameworkrxjs

解决方案


这看起来像你所有的参数forkJoin都是一个普通的对象,它不会接受并抛出你所说的错误。您可以使用 rxjs 将它们转换为可观察的超级简单,它应该可以正常工作。

 // import the of function
 import { of } from 'rxjs';

 // rest of your code goes here, just showing you have to import the above

 apilogin(username: string, password: string) {
    return this.http.post<any>(`http://127.0.0.1:8000/api/token/`, { username, password })
    .pipe(
        switchMap((res: any) => {
            this.user = this.helper.decodeToken(res['access'])
            // run all in paralell
            return forkJoin(
                of(this.storage.set(TOKEN_KEY, res['access'])),
                of(this.storage.set(USERNAME_KEY, username)),
                of(this.storage.set(USER_ID, res['user_id'])),
                of(this.user)
            );
          }),
    // now we know for sure storage values have been set,
    // therefore call checkToken()
        tap(() => this.checkToken()),
        catchError(e => {
            this.showAlert('Oops smth went wrong!');
            throw new Error(e);
        }));

}

推荐阅读