You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular调用API首次加载报rxjs subscribeTo错误 刷新后正常如何解决

问题根因

  1. RxJS catch 操作符返回值不符合规范
    你代码中使用的rxjs catch(rxjs 6+对应catchError)要求必须返回一个Observable流,但是你当前catch分支直接返回了普通Error对象,不属于可订阅的流类型,因此rxjs处理错误时抛出了subscribeTo类型错误。
  2. 首次加载时请求依赖属性未初始化
    首次进入页面时,this.userId、authService.getToken()两个请求依赖的属性还没有完成初始化赋值(比如用户信息是异步从本地存储/后端接口获取,组件首次渲染时还没返回结果),导致第一次请求参数异常、鉴权失败触发catch分支,进而抛出类型错误。刷新页面时这些值已经缓存完成,所以请求正常。
  3. 代码逻辑冗余
    getOwnedEvents方法定义了user_id入参,但实际请求时用的是this.userId,入参完全没有使用,也可能出现参数传递不匹配的问题。

另外你日志中输出的500错误是后端get_profile_image接口的内部错误,和本次的rxjs报错无关,单独排查后端接口逻辑即可。

修复步骤

1. 修正catch分支的返回值

保证catch分支返回可订阅的流,根据你使用的rxjs版本对应修改:

rxjs 5版本:

// 顶部先引入依赖
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';

// 修改getOwnedEvents的catch部分
.catch(
  (error) => {
    let errMsg: string;
    if (error instanceof Response) {
        const body = error.json() || '';
          const err = JSON.stringify(body);
        errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        console.log(errMsg);
    } else {
          errMsg = error.message ? error.message : error.toString();
        console.log(errMsg);
    }
    // 替换原有直接返回error的逻辑,返回Observable错误流
    return Observable.throw(errMsg);
  }
)

rxjs 6+版本:

// 顶部先引入依赖
import { throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

// 修改getOwnedEvents的流处理逻辑为pipe写法
return this.http.get(url, {headers})
  .pipe(
    map((data) => {
      console.log(data);
      return data['payload']['events'];
    }),
    catchError((error) => {
      let errMsg: string;
      if (error instanceof Response) {
          const body = error.json() || '';
            const err = JSON.stringify(body);
          errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
          console.log(errMsg);
      } else {
            errMsg = error.message ? error.message : error.toString();
          console.log(errMsg);
      }
      return throwError(() => new Error(errMsg));
    })
  )

2. 调整请求触发逻辑,保证依赖值初始化完成

不要直接在ngAfterViewInit触发请求,增加依赖值判断,未初始化完成时延迟重试:

onLoadTable() {
  const token = this.authService.getToken();
  // 同时判断token和userId都存在再发起请求
  if(token == null || !this.userId){
    setTimeout(() => this.onLoadTable(), 300);
    return;
  }
  // 原有业务逻辑不变
  this.processing = true;
  this.errorMsg = "";
  console.log("in onLoadTable.");
  this.getOwnedEvents(this.userId)
    .subscribe(
      data => {
        console.log(data);
        this.processing = false;
        this.dataSource.data = data;
        this.paginator.firstPage();
    },
      (err) => {
          this.processing = false;
          var errorReturned = (err.error != undefined && err.error['message'] != undefined) ? err.error['message'] : ""; 
          this.errorMsg = "Error while retrieving event list: " + errorReturned;
    }
  );
}

3. 清理冗余参数

修正getOwnedEvents的参数逻辑,避免混淆:

// 方案1:删除无用的user_id参数
getOwnedEvents(retries:number=0) {
  let url = this.apiURL + 'users/' + this.userId + '/get_all_owned_events';
  // 剩余逻辑不变
}

// 方案2:使用传入的user_id参数
getOwnedEvents(user_id, retries:number=0) {
  let url = this.apiURL + 'users/' + user_id + '/get_all_owned_events';
  // 剩余逻辑不变
}

内容的提问来源于stack exchange,提问作者Nolan Mayersky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 01:45:06