Use Middleware to Handle Asynchronous Actions *spoiler in question*

Tell us what’s happening:
I don’t understand why dispatch(receivedData(data)); should be inside of the setTimeout function. The last test says dispatching handleAsync should dispatch the received data action after a delay, so wouldn’t it make sense to have dispatch(receivedData(data)); after the delay in the setTimeout function has completed? The code passes the tests regardless of whether dispatch(receivedData(data)); is inside the setTimeout function (like my answer below) or outside of it (like this:

const handleAsync = () => {
  return function(dispatch) {
    dispatch(requestingData());

    setTimeout(function() {
      let data = {
        users: ['Jeff', 'William', 'Alice']
      }
    }, 2500);

dispatch(receivedData(data)); 

}

), and I REALLY don’t understand why. Thanks in advance for your help!

Your code so far


const REQUESTING_DATA = 'REQUESTING_DATA'
const RECEIVED_DATA = 'RECEIVED_DATA'

const requestingData = () => { return {type: REQUESTING_DATA} }
const receivedData = (data) => { return {type: RECEIVED_DATA, users: data.users} }

const handleAsync = () => {
  return function(dispatch) {
    dispatch(requestingData());

    setTimeout(function() {
      let data = {
        users: ['Jeff', 'William', 'Alice']
      }
      dispatch(receivedData(data));

    }, 2500);

    
  }
};

const defaultState = {
  fetching: false,
  users: []
};

const asyncDataReducer = (state = defaultState, action) => {
  switch(action.type) {
    case REQUESTING_DATA:
      return {
        fetching: true,
        users: []
      }
    case RECEIVED_DATA:
      return {
        fetching: false,
        users: action.users
      }
    default:
      return state;
  }
};

const store = Redux.createStore(
  asyncDataReducer,
  Redux.applyMiddleware(ReduxThunk.default)
);

Your browser information:

User Agent is: Chrome/71.0.3578.98.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/redux/use-middleware-to-handle-asynchronous-actions

“I don’t understand why dispatch(receivedData(data)); should be inside of the setTimeout function. The last test says dispatching handleAsync should dispatch the received data action after a delay, so wouldn’t it make sense to have dispatch(receivedData(data)); after the delay in the setTimeout function has completed?”

Function calls and expression evaluations in the code block contained within the setTimeout() function are what are executed after the delay, so it makes sense to put the dispatching function inside of the setTimeout(), if you want to delay the dispatching. The example below shows this:

var data;

function myDelayedResponse() {
  setTimeout(() => {
    data = [1, 2, 3];
    console.log('done');
  }, 1000);
  displayData();
}

function displayData() {
  console.log(data);
}

myDelayedResponse();

The console shows:

undefined
done
[Finished in 1.892s]

Now, move the displayData() function call inside of the setTimeout() method

var data;

function myDelayedResponse() {
  setTimeout(() => {
    data = [1, 2, 3];
    console.log('done');
    displayData();
  }, 1000);
  
}

function displayData() {
  console.log(data);
}

myDelayedResponse();

and, at the console, we have:

done
[ 1, 2, 3 ]
[Finished in 1.9s]

This, of course, only answers your first question. Why are the tests passed in both cases? It seems like it shouldn’t be the case if you consider things in terms of scope. I’ve defined data globally for my example. In the fCC exercise data is defined one way within the setTimeout() function scope and possibly defined differently outside of it (as far as things look from the exercise). Unless, I’m overlooking or missing something, it seems there’s something going on in the background that, for example, defines data globally in the same way it’s defined in the setTimeout() function scope, or fCC’s tests aren’t actually checking the value of data for the tests. Or something else. Maybe someone else can shed a little more insight.

2 Likes

Thanks for the explanation (for the first part, at least)! I understand setTimeout better now.