Stretch0
Stretch0

Reputation: 9285

Redux-Thunk "Actions must be plain objects. Use custom middleware for async actions."

Creating my store with Thunk middleware

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
const store = createStore(
    reducer, 
    initialState,
    applyMiddleware(thunk)
);

And creating my action which calls a promise

export function getArticle(url) {
  return function (dispatch) {
    fetchArticle(url).then( 
      article => dispatch(setArticle(article)),
    );
  };
}

function fetchArticle(url) {

  return new Promise((resolve, reject) => {

    request
     .get(url)
     .end( (err, res) => {
       if (err || !res.ok) {
         reject('Oh no! error');
       } else {
         resolve(res.body);
       }
     });

  }) 
}

export function setArticle(article){
  return {
    type: constants.SET_ARTICLE,
    article
  }
}

In my article component I am calling dispatch on componentDidMount()

componentDidMount(){
  this.props.dispatch(
    getArticle('http://api.example.com/')
  );
}

But getting error: "Actions must be plain objects. Use custom middleware for async actions.".

What is wrong with this setup? I have tried calling compose(applyMiddleware(thunk)) but to no avail.

Upvotes: 2

Views: 2904

Answers (4)

Nasir Khan
Nasir Khan

Reputation: 813

In Redux every action must return an object.

You may use:

export const getArticle= url=> dispatch => {
 fetchArticle(url)
   .then(res =>
     dispatch({ type: SET_ARTICLE, payload: res.data })
   )
   .catch(err =>
     dispatch({
       type: GET_ERRORS,
       payload: err.response.data
     })
   );
};

Upvotes: 0

jpdelatorre
jpdelatorre

Reputation: 3593

Your code looks ok except that it's missing how to handle errors (promise rejection). Your api might be returning errors and you're not handling it which could result to that error message.

Try adding

export function getArticle(url) {
  return function (dispatch) {
    fetchArticle(url)
      .then(article => dispatch(setArticle(article)))
      .catch(err => dispatch({ type: 'SOME_ERROR', err }));
  };
}

Upvotes: 2

GibboK
GibboK

Reputation: 73988

Try the following:

export function getArticle(url) {
    return fetchArticle(url).then( 
      article => dispatch(setArticle(article)),
    );  
}

Upvotes: 0

Sergey Yarotskiy
Sergey Yarotskiy

Reputation: 4824

Change

return function (dispatch) {
    fetchArticle(url).then( 
      article => dispatch(setArticle(article)),
    );
  };

To

return function (dispatch) {
    return fetchArticle(url).then( 
      article => dispatch(setArticle(article)),
    );
  };

Upvotes: 0

Related Questions