skip to Main Content

I was trying to use a for loop to loop through an array of string and then use the string id_Arr[i] as a link partial to call an API. In regular JS/Angular all works well but in node the requests gets to the destination but the id_Arr[i] is not taken as a reference to a value in an array, it may be getting called it-self.

So what I am doing is calling the API to get all races going on, filtering to find the live ones – then taking the id’s of the live ones and pushing to an array id_Arr, at which point I initiate a for loop that queries the length of id_Arr and then sends – get requests using the ids from id’Arr

const https = require('node:https');

arr = new Array();
id_Arr = new Array();
race_arr = new Array();


// Get Schedule

var start = new Date();

https.get('link to api', (res) => {
    console.log('statusCode:', res.statusCode);
    console.log('headers:', res.headers);

    res.setEncoding('utf8');
    let rawData = '';
    res.on('data', (chunk) => { rawData += chunk; });
    res.on('end', () => {
        try {
            const jsoData = JSON.parse(rawData);
            arr.push(jsoData.sport_events);
            // console.log(arr);
            var xm = arr[0].filter(function (item) {
                return item.status == 'live';
            });

            for (i = 0; i <= xm.length - 1; i++) {
                id_Arr.push(xm[i].id);
            }
        } catch (e) {
            console.error(e.message);
        }
    });
}).on('error', (e) => {
    console.error(e);
});

//
//
//



// Get Live Circuit

for (i = 0; i <= id_Arr.length - 1; i++) {
    https.get('https://link-toapi/' + id_Arr[i] + '/api-key-rest-of-link', (res) => {
        console.log('statusCode:', res.statusCode);
        console.log('headers:', res.headers);

        res.setEncoding('utf8');
        let rawData = '';
        res.on('data', (chunk) => { rawData += chunk; });
        res.on('end', () => {
            try {
                const parsedDat = JSON.parse(rawData);
                race_arr.push(parsedDat);
                console.log(race_arr);
            } catch (e) {
                console.error(e.message);
            }
        });
    }).on('error', (e) => {
        console.error(e);
    });


}

var time = new Date() - start;

console.log(time)

Why is this not working ? The requests get sent but, the object sent back is just to let me know that then endpoint does not exist. If I am to remove the for loop and directly add the id to the api path, it works just fine.

3

Answers


  1. Chosen as BEST ANSWER

    As @James suggested in his comment

    You may only execute code that depends on id_arr being populated from within the res.on("end") function. For example, wrap the //Get Live Circuit code in a function, and call it after you populate id_arr.

    At this point i did just that, and it worked.

    const https = require('node:https');
    
    arr = new Array();
    id_Arr = new Array();
    race_arr = new Array();
    
    **Created a Function**
    
    function getLiveCircuit(){
    // Get Live Circuit
    
    for (i = 0; i <= id_Arr.length - 1; i++) {
        https.get('https://link-toapi/' + id_Arr[i] + '/api-key-rest-of-link', (res) => {
            console.log('statusCode:', res.statusCode);
            console.log('headers:', res.headers);
    
            res.setEncoding('utf8');
            let rawData = '';
            res.on('data', (chunk) => { rawData += chunk; });
            res.on('end', () => {
                try {
                    const parsedDat = JSON.parse(rawData);
                    race_arr.push(parsedDat);
                    console.log(race_arr);
                } catch (e) {
                    console.error(e.message);
                }
            });
        }).on('error', (e) => {
            console.error(e);
        });
    
    
    }
    }
    
    
    
    // Get Schedule
    
    var start = new Date();
    
    https.get('link to api', (res) => {
        console.log('statusCode:', res.statusCode);
        console.log('headers:', res.headers);
    
        res.setEncoding('utf8');
        let rawData = '';
        res.on('data', (chunk) => { rawData += chunk; });
        res.on('end', () => {
            try {
                const jsoData = JSON.parse(rawData);
                arr.push(jsoData.sport_events);
                // console.log(arr);
                var xm = arr[0].filter(function (item) {
                    return item.status == 'live';
                });
    
                for (i = 0; i <= xm.length - 1; i++) {
                    id_Arr.push(xm[i].id);
                }
    
    **Called The Function in .on**
    getLiveCircuit();
    
            } catch (e) {
                console.error(e.message);
            }
        });
    }).on('error', (e) => {
        console.error(e);
    });
    
    
    var time = new Date() - start;
    
    console.log(time)
    

  2. The requests get sent but, the object sent back is just to let me know that then endpoint does not exist.

    It sounds like the request that’s being made in the second loop may not have the correct ID value you’re expecting it to have. Have you tried logging the 'https://link-toapi/'+id_Arr[i]+'/api-key-rest-of-link' url to ensure its correct?

    Login or Signup to reply.
  3. The loop starts running before the first http.get callback finishes, javascript unlike php, is nonblocking.

    To fix your code, you could use Promises, async await or generators.

    Otherwise rather than a for loop, you could nest the second http call inside the first callback ( a bit dirty but would work ).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search