4

I have a React app which uses Redux and axios. I do not want anything to render before I have some information from the server, which I am retrieving via axios.

I thought that the best way to do this would be by initializing redux state based on that axios call.

However, my function does not seem to be returning anything in time for state initialization...

function getUserData() {
    if (Auth.loggedIn()) { //leaving this here bc it could be important; Auth is another class and loggedIn returns a boolean
        axios.get('/route').then(res => {
            console.log(res.data); //This prints the right thing (an object)
            return res.data;
        });
    } else {
        return ' '; //This works fine; state gets initialized to ' '
    }
}

    let userData = getUserData();
    console.log(userData); //When getUserData() returns ' ', this prints ' '. However, when getUserData() returns my object, this prints undefined.

    const initialState = {
        userData: userData
    };

I realize that this could be a problem with getUserData() being asynchronous, and console.log(userData) running before getUserData() has finished. However, I tried:

getUserData().then(function(userData) {
     console.log(userData);
});

And received 'TypeError: Cannot read property 'then' of undefined'. My function is obviously not returning a promise, so doesn't that mean it's not asynchronous?

Any ideas?

Alternatively, is there a better way of doing this? I could always set initial state and then immediately change it, and make rendering wait for the change to be complete with a conditional render, but that definitely seems worse.

Toby Weed
  • 594
  • 2
  • 7
  • 20
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – user3210641 Jun 17 '18 at 00:15
  • 1
    Do you have any action to update your userData ? If yes, I think you initialize your user in an empty state (null), and once you get your the data, you dispatch and action to update userData – Alan Jun 17 '18 at 00:23
  • @user3210641 No, because (see edit) my function does not return a promise. As far as I can tell, I'm using the right form to return the response of the asynchronous axios call. – Toby Weed Jun 17 '18 at 00:26
  • 1
    @TobyWeed No this is not how you return a value from async call – user3210641 Jun 17 '18 at 00:35
  • Ended up doing that. – Toby Weed Jun 17 '18 at 01:06

1 Answers1

4

You have to return promise from your getUserData function and access it using .then().

function getUserData() {
  return new Promise((resolve, reject) => {
    if (Auth.loggedIn()) {
      axios.get('/route')
        .then(res => resolve(res.data))
        .catch(err => reject(err));
    } else {
      resolve(' ');
    }
  });
};

getUserData().then(function(userData) {
  const initialState = {
    userData: userData, // ' ' or axios result
  };
  console.log(initialState.userData)
}); 
Toby Weed
  • 594
  • 2
  • 7
  • 20
user3210641
  • 1,565
  • 1
  • 10
  • 14