1

Unfortunately, the way the site is setup that I need to retrieve data from, is that this data is spread across multiple sites (the exact same type of data and JSON return format) but they are at different URLs. They are classified by the URLs, so I do need to retain the URLs in order to further classify it throughout the app. I have the following service function where I am trying to pass a set of topics (which are then passed to the URL), retrieve the data and return a single observable. However, this is returning nothing:

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)
      }
    )
}

I am subscribing to it in the template of the component where I am calling this function through an *ngFor plus an async pipe. What am I doing wrong?

Update: I also tried the following:

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))
                }
            }))

2 Answers 2

4

Callback function to the Array.forEach method doesn't expect to receive anything, so maybe you wanted to use Array.map instead.

If you're looking for "more RxJS" approach you could use mergeMap to do something like this:

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);

Eventually you could use concatMap instead of mergeMap to run all requests in order and use concatAll instead of .concatMap(data => data); which makes it a little more obvious what you were trying to do.

Btw, be aware that by using this.items = ... you just assign an Observable to this.items not the result.

Also note that you need to subscribe to the returned Observable if you want to get any results. For example:

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

See live demo: https://jsbin.com/nuzifo/9/edit?html,js,console

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for this - how would I subscribe to the result and not the items? Right now I am modifying my code to have a return on the this.http and removing everything above that like this: `` 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) => {drafting more code here}
@kittycatbytes I'm not sure what you mean. I was talking about the this.items property that you assigned an Observable but from its name it looks like you're expecting to assign the result of the Observable chain to it.
And if you use topicArray.map(....) with the code you have right now you'll make an array of Observables which is probably not what you want.
I updated my original question to try to instead return the response as chained responses. This also is not working though. It does console.log the first 5 items from the first response.
@kittycatbytes Like this for example: jsbin.com/nuzifo/9/edit?html,js,console
|
1

Array.prototype.forEach returns undefined. See MDN for documentation. Use Array.prototype.map instead, and this.items will be an array of observables that you can then do whatever you want with.

1 Comment

Changing forEach to map does not work either. In both cases, it does not console.log the data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.