30

Here is the code I'm playing with

import { createStore, applyMiddleware } from 'redux' import thunk from 'redux-thunk' import axios from 'axios' const initialState = { user: {}, requesting: false, err: null } const reducer = (state = initialState, action) => { switch (action.type) { case 'REQ_USER_INIT': return { ...state, requesting: true } case 'REQ_USER_DATA': return { ...state, requesting: false, user: action.user } case 'REQ_USER_ERR': return { ...state, requesting: false, err: action.err } } return state; } const logger = (store) => (next) => (action) => { let previous = JSON.stringify(store.getState()) next(action) console.log( 'action: ' + JSON.stringify(action) + '\n\tprevious: ' + previous + '\n\tcurrent: ' + JSON.stringify(store.getState()) ) } const store = createStore(reducer, applyMiddleware(logger, thunk)) store.dispatch((dispatch) => { dispatch({ type: 'REQ_USER_INIT' }) // Fake Online REST API for Testing and Prototyping // break url to get an error response let usersEndpoint = 'https://jsonplaceholder.typicode.com/users/1' axios.get(usersEndpoint) .then((response) => { dispatch({ type: 'REQ_USER_DATA', user: { id: response.data.id, username: response.data.username, email: response.data.email, } }) }) .catch((error) => { dispatch({ type: 'REQ_USER_ERR', err: error.message }) }) }) 

I believe it is pretty straightforward, right? I dispatch REQ_USER_INIT and then REQ_USER_DATA once the response is received. I should log two actions, however I get 3. Second action is undefined and I am strugling to figure out what causes it. Is it a bug with redux-thunk or am I doing something wrong?

Here is the output from my console:

action: {"type":"REQ_USER_INIT"} ·previous: {"user":{},"requesting":false,"err":null} ·current: {"user":{},"requesting":true,"err":null} action: undefined ·previous: {"user":{},"requesting":false,"err":null} ·current: {"user":{},"requesting":true,"err":null} action: {"type":"REQ_USER_DATA","user":{"id":1,"username":"Bret","email":"[email protected]"}} ·previous: {"user":{},"requesting":true,"err":null} ·current: {"user":{"id":1,"username":"Bret","email":"[email protected]"},"requesting":false,"err":null} 

1 Answer 1

50

The order of middlewares matters. Try making logger last

const store = createStore(reducer, applyMiddleware(thunk, logger)) 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! Perfect. Wouldn't come up with that on my own. Would you care to explain it why order matters please?
"why order matters" imagine there is an array of middlewares middlewares and dispatch will pass every event to each middleware from left to right. So if you have middleware that transforms action somehow (like thunk does) you do want it to run before logger logs it to console.
Makes perfect sense. Thank you. I am referencing this answer int github issue

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.