0

I use FACEIT API to get 5 nicknames from a certain match. I want to use that 5 nicknames and store them inside players array and then reuse it to make 5 new url-s that are going to allow me to get more information for each player. Problem is that after I push nicknames to players array I only get undefined.

var express = require("express");
var app = express();
var request = require('request');

var players = [];

var headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer <my API code which I don't want to display>'
};

var options = {
    url: 'https://open.faceit.com/data/v4/matches/cdc61c3b-2f9b-4c92-a2c9-ea1cfb54eb51',
    headers: headers
};

request(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var parsedBody = JSON.parse(body);
        for (var i = 0; i < 5; i++) {
            players.push(parsedBody["teams"]["faction1"]["roster_v1"][i]["nickname"]);
        }
    }
});

var options2 = {
    // I get "https://open.faceit.com/data/v4/players?nickname=undefined" instead of 
    // "https://open.faceit.com/data/v4/players?nickname=lonely52"
    url: "https://open.faceit.com/data/v4/players?nickname=" + players[0], 
    headers: headers
};

request(options2, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var parsedBody = JSON.parse(body);
        console.log(parsedBody["nickname"]); // UNDEFINED
    }
});

app.get("/", function(req, res) {
    res.send(players);  // ["lonely52","Crowned","pstarbang","wolf1E_KZ","Fr0let"]
});

app.listen(3000, function() {
    console.log("Listening on port 3000...");
});
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Sven Jul 09 '18 at 11:27
  • I still don't understand how to fix it in my code. – mesopotamija9 Jul 09 '18 at 11:35
  • i'll reccommend you to study async nature of javascript play a little bit with it. Code has many flaws and it will only confuse you if someone just throws correct answe – Ganesh Karewad Jul 09 '18 at 12:24

2 Answers2

0

I think your request number 2 is done before the request 1 has the time to push into the variable. Your should Wrap all theses request into a big async function. And await them.Sthing like this :

        async function myreq()
        {
           let j = await request(options, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var parsedBody = JSON.parse(body);
                for (var i = 0; i < 5; i++) {
                    players.push(parsedBody["teams"]["faction1"]["roster_v1"][i]["nickname"]);
                }
            }
        });

        var options2 = {
            // I get "https://open.faceit.com/data/v4/players?nickname=undefined" instead of 
            // "https://open.faceit.com/data/v4/players?nickname=lonely52"
            url: "https://open.faceit.com/data/v4/players?nickname=" + players[0], 
            headers: headers
        };

        request(options2, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var parsedBody = JSON.parse(body);
                console.log(parsedBody["nickname"]); // UNDEFINED
            }
        });
    }

myreq();
AlThi
  • 1
  • 1
  • 2
0

Cause: You are making REST API calls, which are asynchronous. Your "player details" API is being called even before you get response from the "list of players" API. Because of this, when you are making the request, there is nothing in the array and player[0] is undefined

Solution:

Just call the "player details" API after you get the response from "list of players" API, in its callback:

request(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var playerList = JSON.parse(body);
        for (var i = 0; i < 5; i++) {
            var nickname = playerList["teams"]["faction1"]["roster_v1"][i]["nickname"]);

            var options2 = {
                url: "https://open.faceit.com/data/v4/players?nickname=" + nickname, 
                headers: headers
            };

            request(options2, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    var playerDetails = JSON.parse(body);
                    console.log(playerDetails["nickname"]); // UNDEFINED
                }
            });
        }
    }
});

Here you don't even have to push the player names in an array, you can immediately make the requests.
This should get the job done.

Alternatives:
There are other ways to implement this like using async-await or using async.js or increment a counter everytime you get response from first API, push data in array, and once you get all responses, call a function that will iterate over array and call the second API on all of them.

PS: Look into nodejs callbacks, they are fun and will help you with issues like this one.

Dushyant Bangal
  • 6,048
  • 8
  • 48
  • 80