duwerq
duwerq

Reputation: 99

Redux Thunk Action = Undefined in componentWillMount

I'm trying to dispatch a function from componentWillMount. The bound action creator function fetchDraftAdventures works outside of componentWillMount but not inside.

componentWillMount() {
    let {draftAdventures, editableAdventures} = this.props;
    console.log("this props")
    this.props.fetchDraftAdventures(1);
    console.log(' adventures props', this.props)
  }

App connected

export default withRouter(connect(
  state => {
    return {
      editableAdventures: state.editableAdventures,
      draftAdventures: state.draftAdventures,
    };
  },
  dispatch => ({
    fetchAdventureEditable: bindActionCreators(fetchAdventureEditable, dispatch),
    fetchEditableAdventures: bindActionCreators(fetchEditableAdventures, dispatch),
    fetchAdventureDraft: bindActionCreators(fetchAdventureDraft, dispatch),
    fetchDraftAdventures: bindActionCreators(fetchDraftAdventures, dispatch),
    dispatch
  })
)(AdventuresDashboard));

Here's the action itself:

// Constants
import {
  GET_DRAFT_ADVENTURES_REQUESTED,
    GET_DRAFT_ADVENTURES_SUCCEEDED,
    GET_DRAFT_ADVENTURES_REJECTED
} from '../../../constants/Actions'

import {get} from '../../../lib/request';

const DraftAdventures = (args) => {
  console.log('draft adventures', args)
  const Authorization = localStorage.getItem('authToken');

  const pageNumber = args;
  const lastIndex = pageNumber.length - 1;
  let pageParam = '';

  if (pageNumber[lastIndex]) {
    pageParam = `?page=${pageNumber[lastIndex]}`

    return dispatch => {

      dispatch({ type: GET_DRAFT_ADVENTURES_REQUESTED, payload: `Fetching Draft Adventures` })
      get(`/draft-adventures/${pageParam}&ordering=-updated_at`, {},
      {Authorization})
      .then(response => {
        if (response) {
          if (response.data) {
            let page = null;
            if (response.data.next !== null) {
              page = response.data.next.split('page=')[1];
              page = Number(page);
            }
            dispatch({ type: GET_DRAFT_ADVENTURES_SUCCEEDED, payload: response.data, pageNumber: Number(page)})

          } else {
            dispatch({ type: GET_DRAFT_ADVENTURES_REJECTED, payload: 'NULL response.data' })
          }
        } else {
          dispatch({ type: GET_DRAFT_ADVENTURES_REJECTED, payload: 'NULL response' })
        }
      }).catch(error => {
        console.log('errorer', error)
        dispatch({ type: GET_DRAFT_ADVENTURES_REJECTED, payload: error })
      })

    }
  }
};

export default (DraftAdventures);

The response to this is the following stack trace: enter image description here

From what I can tell, the action is being passed from the thunk middleware to the router middleware is undefined. Inside my fetchDraftAdventure function, dispatch({ type: GET_DRAFT_ADVENTURES_REQUESTED, payload: 'Fetching Draft Adventures' }) never gets called. Why not?

Also, my store config file:

// Libraries
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import {logger} from 'redux-logger';

import createHistory from 'history/createBrowserHistory'
import { routerMiddleware } from 'react-router-redux'

// Components
import DevTools from '../devTools/DevTools';

// Reducers
import reducer from '../reducers';

// Config
import reduxLoggerConfig from '../config/reduxLoggerConfig';

//const logger = createLogger(reduxLoggerConfig);

const history = createHistory()
const middlewareRouter = routerMiddleware(history)


const createDevStoreWithMiddleware = compose(
  applyMiddleware(thunk, middlewareRouter, logger),
  DevTools.instrument()
)(createStore);

console.log('createDev store', createDevStoreWithMiddleware(reducer))
export default function configureStore() {

  var store = createDevStoreWithMiddleware(reducer);

  // enable webpack hot module replacement for reducers
  if (module.hot && process.env.BUILD_TARGET === 'local') {
    module.hot.accept('../reducers/index.js', () => {
      const nextRootReducer = require('../reducers');
      store.replaceReducer(nextRootReducer);
    });
  }

  return store;
}

Upvotes: 2

Views: 415

Answers (2)

Brandon
Brandon

Reputation: 39202

If this condition is not true: if (pageNumber[lastIndex]), then your action creator DraftAdventures does not return anything (e.g. it returns undefined. Redux tries to dispatch this undefined action and you get your error.

action creators (DraftAdventures in this example) need to always return an action. That action can either be a simple object, or a thunk (aka function), or something else you've installed redux middleware to handle.

Your action creator sometimes returns a thunk (good!) and sometimes returns undefined (bad!)

Upvotes: 1

Sagiv b.g
Sagiv b.g

Reputation: 31024

I think the problem is with your "thunk".

This is not a thunk signature, you are not returning a function.

Change to this:

const DraftAdventures = (args) => ({dispatch}) => {...  

redux-thunk check to see if the object is typeof function.
Your return is inside an if statement.

Upvotes: 0

Related Questions