【问题标题】:Angular Service function not returning anything, trying to do multiple http requests and return single observableAngular Service 函数不返回任何内容,尝试执行多个 http 请求并返回单个 observable
【发布时间】:2017-06-07 01:14:18
【问题描述】:

不幸的是,我需要从中检索数据的站点设置方式是,这些数据分布在多个站点(完全相同的数据类型和 JSON 返回格式),但它们位于不同的 URL。它们按 URL 分类,因此我确实需要保留 URL 以便在整个应用程序中进一步对其进行分类。我有以下服务功能,我试图传递一组主题(然后将其传递给 URL),检索数据并返回单个 observable。但是,这没有返回任何内容:

getDataTopicItems(topicArray) {
    return this.items = topicArray.forEach((topic, i, topicArray) => {
        return this.http.get(this.baseUrl + topic + "/_api/Web/Lists/GetByTitle('What''s New')/items", this.options)
            .map(res => res.json())
            .map(items => items.d.results)
            .do(data => console.log(data))
            .concatMap(data => data)
      }
    )
}

我在组件的模板中订阅它,我通过 *ngFor 和异步管道调用此函数。我做错了什么?

更新:我还尝试了以下方法:

return this.http.get(this.baseUrl + topicArray[0] + this.policyOptions, this.options)
            .map(res => res.json())
            .map(items => this.policies = items.d.results)
            .do(data => console.log(data))
            .flatMap((policies) => topicArray.forEach((topic, i, topicArray) => {
                if (i < 0) {
                    this.http.get(this.baseUrl + topic + this.policyOptions)
                        .map(res => res.json())
                        .map(items => this.policies = items.d.results)
                        .do(data => console.log(data))
                }
            }))

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    Array.forEach 方法的回调函数不希望收到任何内容,因此您可能想改用 Array.map

    如果你正在寻找“更多 RxJS”的方法,你可以使用 mergeMap 来做这样的事情:

    return Observable.from(topicArray)
        .mergeMap(topic => this.http.get(this.baseUrl + topic + "/_api/Web/Lists/GetByTitle('What''s New')/items", this.options)
            .map(res => res.json())
            .map(items => items.d.results)
            .do(data => console.log(data))
            .concatMap(data => data);
    

    最终,您可以使用concatMap 而不是mergeMap 来按顺序运行所有请求,并使用concatAll 而不是.concatMap(data =&gt; data);,这使得您尝试做的事情更加明显。

    顺便说一句,请注意,使用 this.items = ... 您只需将 Observable 分配给 this.items 而不是结果。

    另外请注意,如果您想获得任何结果,您需要订阅返回的 Observable。例如:

    getDataTopicItems([...]).subscribe(result => this.items = result);
    

    观看现场演示:https://jsbin.com/nuzifo/9/edit?html,js,console

    【讨论】:

    • 谢谢你 - 我将如何订阅结果而不是项目?现在我正在修改我的代码以返回 this.http 并删除上面的所有内容,如下所示:``return this.http.get(this.baseUrl + topicArray[0] + "/_api/Web/Lists/ GetByTitle('What's New')/items", this.options) .map(res => res.json()) .map(items => items.d.results) .do(data => console. log(data)) .flatMap(data => topicArray.forEach((topic, i, topicArray) => {在这里起草更多代码}
    • @kittycatbytes 我不确定你的意思。我说的是您分配了一个 Observable 的 this.items 属性,但从它的名称来看,您似乎希望将 Observable 链的结果分配给它。
    • 如果你将topicArray.map(....) 与你现在拥有的代码一起使用,你将创建一个 Observables 数组,这可能不是你想要的。
    • 我更新了我的原始问题以尝试将响应作为链接响应返回。这也行不通。它确实 console.log 来自第一个响应的前 5 个项目。
    • @kittycatbytes 例如:jsbin.com/nuzifo/9/edit?html,js,console
    【解决方案2】:

    Array.prototype.forEach 返回undefinedSee MDN for documentation。改用Array.prototype.mapthis.items 将是一组可观察对象,然后您可以随心所欲地做任何事情。

    【讨论】:

    • 将 forEach 更改为 map 也不起作用。在这两种情况下,它都不会控制台记录数据。
    猜你喜欢
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2020-06-24
    • 2020-07-09
    • 2021-07-07
    相关资源
    最近更新 更多