首页 > 解决方案 > rxjs/ajax 响应无法分配给对象“[object Object]”的只读属性“taskData”

问题描述

在一个 Angular 应用程序中,我创建了一个通过 GET 从后端获取 json 对象的服务。

当我使用这个fetch代码块时,一切正常:

fetchNode(nodePath: string): Promise<CrxApiNode> {
const {token} = this.authInfo$;
return fetch(`${nodesUrl}?path=${encodeURIComponent(nodePath)}`,
  {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${token}`,
      Accept: 'application/json; charset=utf-8'
    }
  }
).then(res => {
    return res.json();
}).catch(e => {
  console.log('error');
});

}

当使用 rxjs/ajax 执行相同的请求时:

  loadNode(nodePath: string): Observable<CrxApiNode> {
const {token} = this.authInfo$;
  // this leads to the error
return ajax.getJSON(`${nodesUrl}?path=${encodeURIComponent(nodePath)}`, {
  Authorization: `Bearer ${token}`,
  Accept: 'application/json; charset=utf-8'
}).pipe(
  map(node => {
    return node;
  }),
  catchError(error => {
    // here the error occurs: Cannot assign to read only property 'taskData' of object '[object Object]'
    console.log('error: ', error);
    return of(error);
  }));

}

我收到错误(由 ajax(...) 抛出):

"TypeError: Cannot assign to read only property 'taskData' of object '[object Object]'
at XMLHttpRequest.addEventListener (http://localhost:4200/polyfills.js:1939:39)
at XMLHttpRequest.desc.set [as ontimeout] (http://localhost:4200/polyfills.js:1292:24)
at AjaxSubscriber.setupEvents (http://localhost:4200/vendor.js:78731:23)
at AjaxSubscriber.send (http://localhost:4200/vendor.js:78652:18)
at new AjaxSubscriber (http://localhost:4200/vendor.js:78634:14)
at AjaxObservable._subscribe (http://localhost:4200/vendor.js:78605:16)
at AjaxObservable._trySubscribe (http://localhost:4200/vendor.js:77010:25)
at AjaxObservable.subscribe (http://localhost:4200/vendor.js:76996:22)
at MapOperator.call (http://localhost:4200/vendor.js:82439:23)
at Observable.subscribe (http://localhost:4200/vendor.js:76991:31)"
enter code here

由于我对 rxjs 相当陌生,我正在努力分析错误 - 这里有什么区别,为什么 rxjs 变体没有按预期工作?

标签: javascriptangularajaxrxjs

解决方案


在您的第一个示例中,您捕获错误并记录它。结果,错误现在“消失了”。

在第二个示例中,您也捕获了错误,也记录了它,但随后错误发生了。“catchError”将从流中捕获错误,并将新的值(不是错误)返回到流中。这样做的原因是,您现在能够捕获错误并将其替换为默认值,以便为用户尽可能顺利地处理错误。

因此,您的流现在会发出一个错误对象。不将其视为错误。我假设稍后您会调用“myEmitedValue.taskData”。但是“myEmitedValue”不是来自后端调用的 JSON,而是错误对象。因此没有“taskData”。

如果您想“重新抛出”错误,您可以改为

return throwError(err)

我用几个例子创建了一个堆栈闪电战。


推荐阅读