Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating recursive Observable loop?

I have a hard time figuring out how to create a recursive loop to api calls with Observables.

Scenario: I call external API, which returns something like this:

{
 data: {something, something, something},
 next: "url for next set of data"
}

I need to keep on calling the same function to gather all the data into a single object as long as the response has value in the next.

I managed to do this on another project with Promises where I map the data returned into single array by using the concat() function but I somehow cannot get my head around understanding how I should do this with Observables.

Working example with using promises:

getData: function(url, params, headers){
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params,
            headers: headers,
        }).then((response) => {
            let responseData = response.data.data[0];
            if (response.data.next) {
                this.getData(response.data.next, {}).then((resp) => {
                    for (let dataSet of responseData.dataSets) {
                        let row = resp.dataSets.find(i => i.variable === dataSet.variable)
                        if (row) {
                            dataSet.data = dataSet.data.concat(row.data)
                        }
                    }
                    resolve(responseData);
                }).catch((error) => {
                    reject(error)
                })

            } else {
                resolve(responseData);
            }
        }).catch(error => {
            reject(error)
        })
    })
}
like image 264
Melfarion Avatar asked Oct 17 '25 14:10

Melfarion


1 Answers

You can use the .expand() operator. The terminating condition for this recursion is when the next property is falsy. Use a ternary operator and the code is just one liner:

expand(({data, next}) => next ? getData(next): Observable.empty() )
    .subscribe(result => console.log(result));

Here is the working JSBin. I mocked quite a few stuffs but it should be quite trivial.

like image 185
CozyAzure Avatar answered Oct 19 '25 11:10

CozyAzure



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!