Why am I getting back "undefined" from my Axios call, when it should return me objects?

Problem Intro:

In my React app I'm making some API calls to Github to fetch some user data. In another function I call these functions and wait for it with Axios's .all() method.

I want to fetch the data and do something with it using .then() but the returned value is just an array with 2 times undefined

What is the expected thing to happen:

It should return me 2 player objects with profile infos in the profile key of the object and a score value in the score key of the object.

What is my app doing in a nutshell?

It fetches the data from 2 usernames and they can "battle" each other. It just fetches the score and the followers and returns a sum. At the end it (should) returns an array with 2 player objects already sorted with the winner in the first place (exampleArray[0]).

General information's It's an react app using components. It's really about one very tiny component and the helper functions in another file.

Here is where I call my custom function (the one returning undefined):

componentDidMount() {
    const players = queryString.parse(this.props.location.search); //<== the usernames
    const playersArray = [players.playerOneName, players.playerTwoName];
    console.log(playersArray); // <== this logs the output as expected (an array with 2 usernames)

    battle(playersArray).then((data) => {   // <== the function it's all about
        console.log(data); // <== data is => [undefined, undefined];
    })
}

Next is the battle function from above that uses 2 other functions:

battle

export function battle(players) { // <== players aray with 2 usernames as string
return axios.all(players.map(getUserData)) // <== look 1 function below
    .then(sortPlayers) // <== two functions below
    .catch(handleError)
}

getUserData

let getUserData = (player) => {
axios.all([
    getProfile(player),
    getRepos(player)
]).then((data) => {
    return {
        profile: data[0],
        score: calculateScore(data[0], data[1])
    }
})
}

sortPlayers

let sortPlayers = (players) => {

return players.sort((a, b) => {
    return b.score - a.score;
})
}

Ok so they also use other functions but they are really not too complicated. Let me know when you need examples from the other little helpers too.

I tried it with placing the debugger in different spots in the code and console logged different things, but I can't come through (first time I'm really working with promises). Sitting now 2 hours in front of this tiny problem and I can't figure it out.

I think the problem lies somewhere in battle function itself or getUserData

At the end a little screenshot, what the output of my console.log looks: http://prntscr.com/hz5abq

Thanks in advance

2 answers

  • answered 2018-01-11 19:40 Nicholas Tower

    getUserData needs to return the promise that it creates. At the moment it's not returning anything, so an implicit undefined is returned, and thus players.map(getUserData) results in an array of [undefined, undefined]

    Ie, do this:

    let getUserData = (player) => {
        // VVV added return statement
        return axios.all([
            getProfile(player),
            getRepos(player)
        ]).then((data) => {
            return {
                profile: data[0],
                score: calculateScore(data[0], data[1])
            }
        })
    }
    

  • answered 2018-01-11 19:40 charlietfl

    You don't have anything being returned in getUserData . Either add a return or remove the {} wrapping axios.all

    let getUserData = (player) => {
    
        return axios.all([
            getProfile(player),
            getRepos(player)
        ]).then((data) => {
            return {
                profile: data[0],
                score: calculateScore(data[0], data[1])
            }
        })
    
    }