Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux Actions must be plain objects. Use custom middleware for async action

I'm getting the error "Redux Actions must be plain objects. Use custom middleware for async action." with the below code.

export const getFriends = () => async(): Action => {

  const requestConfig = {
    httpMethod: 'GET',
    version: 'v2.7',
  };
  let hasMore = false;
  let friends = [];

  do {
    const infoRequest = new GraphRequest(
    '/me/friends',
    requestConfig,
    (error, result) => {
      if (error) {
        alert('Error fetching data facebook friends');
      } else {
        result.data.forEach((value) => {
            friends.push(value)
        });
        if (result.paging && result.paging.next) {
          hasMore = true;
          requestConfig.parameters.after = result.paging.cursors.after;
        } else {
          hasMore = false;
        }
      }
    });
    await new GraphRequestManager().addRequest(infoRequest).start();
  } while (hasMore);
  return {
    type: 'GET_FRIENDS',
    payload: friends    // this is empty because there is no await on GraphAPI
  };
};

If I remove the async and await, the friend returned is empty because function call returned before GraphAPI call returned

export const getFriends = () => (): Action => {

  const requestConfig = {
    httpMethod: 'GET',
    version: 'v2.7',
  };
  let hasMore = false;
  let friends = [];

  do {
    const infoRequest = new GraphRequest(
    '/me/friends',
    requestConfig,
    (error, result) => {
      if (error) {
        alert('Error fetching data facebook friends');
      } else {
        result.data.forEach((value) => {
            friends.push(value)
        });
        if (result.paging && result.paging.next) {
          hasMore = true;
          requestConfig.parameters.after = result.paging.cursors.after;
        } else {
          hasMore = false;
        }
      }
    });
    new GraphRequestManager().addRequest(infoRequest).start();
  } while (hasMore);
  return {
    type: 'GET_FRIENDS',
    payload: friends    // this is empty because there is no await on GraphAPI
  };
};
like image 313
user43286 Avatar asked Dec 15 '16 20:12

user43286


People also ask

Are Redux actions asynchronous?

Its infrastructure is based on functional foundations and lets you easily build testable code. However, the flow of Redux's state management tasks is completely synchronous: dispatching an action immediately generates the chain of calls to middleware and reducers to carry out the state transition.

What is asyncthunk?

`createAsyncThunk() It generates promise lifecycle action types based on the action type prefix that you pass in, and returns a thunk action creator that will run the promise callback and dispatch the lifecycle actions based on the returned promise.


1 Answers

The error means exactly what it sounds like. Redux is expecting a plain object. I see the question tagged with redux-thunk. If you are using redux-thunk, perhaps you don't have the store set up with the middleware properly. If you aren't using redux-thunk then I would recommend it as the go-to library for dispatching async actions.

This will give you great insight about dispatching redux actions that aren't plain objects. How to dispatch a Redux action with a timeout?

edit: You are missing the actual dispatch and are trying to simply return plain object... need to return a dispatch... something like the following (haven't testing, but should get you close):

    export const getFriends = () => {
      return (dispatch) => {
        const requestConfig = {
          httpMethod: 'GET',
          version: 'v2.7',
        };
        let hasMore = false;
        let friends = [];

        do {
          const infoRequest = new GraphRequest(
            '/me/friends',
            requestConfig,
            (error, result) => {
              if (error) {
                alert('Error fetching data facebook friends');
              } else {
                result.data.forEach((value) => {
                    friends.push(value)
                });
                if (result.paging && result.paging.next) {
                  hasMore = true;
                  requestConfig.parameters.after = result.paging.cursors.after;
                } else {
                  hasMore = false;
                  return dispatch({
                    type: 'GET_FRIENDS',
                    payload: friends               
                  });
                }
              }
          });
          await new GraphRequestManager().addRequest(infoRequest).start();
        } while (hasMore);
      }
    };
like image 69
Travis White Avatar answered Nov 15 '22 10:11

Travis White