【问题标题】:Can't handle json files returned by Observable.forkJoin()无法处理 Observable.forkJoin() 返回的 json 文件
【发布时间】:2017-12-25 08:07:23
【问题描述】:

我正在使用 Angular2 和 nodejs rest api。我必须为同一任务执行一个或多个 http 请求,因此我使用 Observable.forkJoin() 等待所有请求完成。 我使用 json 解析方法映射结果,然后订阅此结果,但 我无法像以前那样从结果中获取任何 json 属性。

我的服务方法返回 Observable.forkJoin() 本身:

public rename(file:MyFile, newName:string){
    let requests = new Array();
    for(let i=0; i<file.sources.length; i++){
        let url:string = this.serverUrl;
        if(src.name === "src1"){
            url += "rename/src1";
        } else if (src.name === "src2" ){
            url += "rename/src2";
        }
        requests[i] = this.http.get(url)
                  .map((res:Response) => res.json())
                  .catch(this.handleError);
    }
    return Observable.forkJoin(requests);
}

然后我在别处用另一种方法订阅它:

this.api.rename(this.selectedFile, newFileName).subscribe(
    rep => {
      // The editor tells me "Property 'name' doesn't exist on type '{}'."
      console.log(rep[0].name); 
    },
    err => { console.error(err); }
  );

服务器正确响应我询问的数据。 rep[0] 设置正确,如下所示:

Object {name: "res.png", id: "HyrBvB6H-", size: 0, type: "", isShared: false…}

我想这是一个打字问题。通常,通过一个简单的 http.get 请求,它会返回一个“任意”对象。这里它返回一个 '[]{}' 对象。 res[0] 是一个“{}”对象,我无法获取它的 json 属性。

我是否正确使用了 Observer.forkJoin()?我错过了什么吗?

提前感谢您的帮助:)

【问题讨论】:

  • 如果你让new Array&lt;any&gt;();怎么办?

标签: json angular observable fork-join


【解决方案1】:

http.get是一个异步进程,所以不能使用for循环。
从语法上讲,你必须将 get 嵌套在 forkJoin 中,所以你有这样的东西。您可以先使用 for 循环构建一个 url 数组。:

return Observable.forkJoin([
    this.http.get(url[1]).map(res => res.json()),
    this.http.get(url[2]).map(res => res.json()),
    this.http.get(url[3]).map(res => res.json())
  ])
  .map((data: any[]) => {
     this.part1 = data[0];
     this.part2 = data[1];
     this.part3 = data[2];
  });

我想知道你是否可以做这样的事情。我明天试试。来晚了。。

return Observable.forkJoin(let req = [];
  for(let i=0; i<file.sources.length; i++){
      req[i] = this.http.get(url[i]).map(res => res.json())
  }
)

【讨论】:

  • 请注意,对于当前最新的 tsc (2.4.1) 和 angular (4.3.0),您需要删除 .forkJoin() 的数组表示法:stackoverflow.com/questions/45020250/…
  • 哦......那听起来很有希望......所以也许 for 循环 cal 嵌套没有我分配的 req 数组......
  • 感谢您的回答 :) 问题纯粹出在对象类型上。我将根据您指出的内容删除数组符号@msanford
  • @JGFMK 您可以只传递函数列表,因为.forkJoin() 使用...rest 参数:您只需删除括号并像往常一样使用它。
  • @msanford 所以你是说我们现在可以做任何一种方式?
【解决方案2】:

如果编辑器在抱怨并且代码执行时不是错误,则很可能是打字问题。您可以将rename()的返回类型设置为:

public rename(file:MyFile, newName:string): Observable<any[]> { }

这应该允许您访问内部结果的属性,例如name

或者您可以在subscribe() 中键入rep 数组为any[]

this.api.rename(this.selectedFile, newFileName).subscribe(
    (rep: any[]) => {
      console.log(rep[0].name); 
    },
    err => { console.error(err); }
);

如果所有其他方法都失败或不适用于您的解决方案,您可以使用类型断言将rep 视为any[]

this.api.rename(this.selectedFile, newFileName).subscribe(
    rep => {
      const responses = rep as any as any[];
      console.log(responses[0].name); 
    },
    err => { console.error(err); }
);

如果不同端点的结果结构一致,最好创建一个接口/类来替换any[]

希望对您有所帮助!

【讨论】:

  • 我觉得很愚蠢,我只是在方法上添加了返回类型 Observable,它立即运行良好。我虽然因为“任何”而没有必要。谢谢!
猜你喜欢
  • 2015-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2014-03-17
  • 1970-01-01
相关资源
最近更新 更多