1

I'm following the same steps as "A simplified approach to calling APIs with redux" to do api calls.

However i'm attempting to do a nested call when i get my results but the for loop is not waiting so my returned data is all in the wrong place. i'm using superagent in react to do this.

Thanks

here is my code

import request from 'superagent';
const dataService =

request
        .get('http://my-api.com/api/sets/coll_e8400ca3aebb4f70baf74a81aefd5a78/items/')
        .end((err, res) => {
            if (err) {
                return "error";
            }
            const data = JSON.parse(res.text);

        let sections = new Array(),
            section = null,
            episodes = null;

        for (var i = 0; i < data.objects.length; i++) {
            let type = data.objects[i].content_type.toLowerCase();

            if(type !== "episode") {
                if (section !== null) {
                    section.episodes = episodes;
                    sections.push(section);
                }
                section = new Object();
                episodes = new Array();
                section.header = data.objects[i].heading;
            }

            if(type === "episode") {
                var url = `http://my-api.com:8000${data.objects[i].content_url}`;
                request
                    .get(url)
                    .end((err, res) => {
                    const data2 = JSON.parse(res.text);

                    console.log("data2", data2);
                    var episode = new Object();
                    episode.title = data2.title;
                    episodes.push(episode);
                });
            }
        }

        section.episodes = episodes;
        sections.push(section);

        console.log("sections", sections);
    })

export default dataService

Edit: The issue is happening on the inner request where I’m getting the episodes. var url = http://my-api.com:8000${data.objects[i].content_url};

Adam
  • 1,136
  • 8
  • 26
  • 51

1 Answers1

1

From your description I am still unsure where you need async. I will guess. But I would suggest you use Promise.all(). I will show an example below.

import request from 'superagent';
const dataService =

request
        .get('http://my-api.com/api/sets/coll_e8400ca3aebb4f70baf74a81aefd5a78/items/')
        .end((err, res) => {
            if (err) {
                return "error";
            }
            const data = JSON.parse(res.text);

        let sections = new Array(),
            section = null,
            episodes = null;

        Promise.all(for (var i = 0; i < data.objects.length; i++) {
            let type = data.objects[i].content_type.toLowerCase();

            if(type !== "episode") {
                if (section !== null) {
                    section.episodes = episodes;
                    sections.push(section);
                }
                section = new Object();
                episodes = new Array();
                section.header = data.objects[i].heading;
            }

            if(type === "episode") {
                var url = `http://my-api.com:8000${data.objects[i].content_url}`;
                request
                    .get(url)
                    .end((err, res) => {
                    const data2 = JSON.parse(res.text);

                    console.log("data2", data2);
                    var episode = new Object();
                    episode.title = data2.title;
                    episodes.push(episode);
                });
            }
        }).then(() => {
            section.episodes = episodes;
            sections.push(section);

            console.log("sections", sections);
          }


    })

export default dataService

UPDATE-----

Promise.all(if (type === "episode") {
    var url = `http://my-api.com:8000${data.objects[i].content_url}`;
    request
        //with superagent you can use promises like such.
        .get(url)
        .then((err, res) => {
            const data2 = JSON.parse(res.text);

            console.log("data2", data2);
            var episode = new Object();
            episode.title = data2.title;
            episodes.push(episode);
        });
}).then(() => {
    section.episodes = episodes;
    sections.push(section);

    console.log("sections", sections);
})
Gavin Thomas
  • 1,827
  • 2
  • 11
  • 17
  • I’ve added more information as to where the issue is happening but think promises are the answer but might need on the inner request if the type is episode – Adam Dec 29 '17 at 20:16
  • Check out the updates and see if they help. With superagent you can utilize their built in Promise with .then after .get – Gavin Thomas Dec 29 '17 at 20:32
  • I'm getting an error Promise.all(for (var i = 0; i < data.objects.length; i++) says expression expected – Adam Dec 29 '17 at 21:03
  • This is more sudo code. I suggest you read about Promise.all(), New Promise(), and packages like BlueBird. Understanding Async is fundamental when you start building complex methods. They might also allow you to modularize your code into seperate functions. Like if your first IF is true, fire handleThisCase(), where you could promisfy it with Bluebird. – Gavin Thomas Dec 29 '17 at 21:11
  • Thanks that got me on the right path using promise.all and looping through my data that way and using .then to run additional calls after. – Adam Dec 30 '17 at 13:07