userfi
userfi

Reputation: 165

async call with reducer not work

i'm trying to implementing a Redux action that retrieves some json data with an asynchronous call using React Native. I put the function fetchRestaurant() everywhere inside component but i still get this error:

Cannot read property 'type of undefined.

here's the code inside action/restaurant.js

export function setFetchedRestaurant(restaurants){
  return   Object.assign({ type: types.SET_FETCHED_RESTAURANT, restaurants:restaurants } );
}



export function fetchRestaurant(){
  var restaurants;
  fetch('https://appetizing.000webhostapp.com/connect.php').then((response) => response.text()).then((responseText) => { dispatch(setFetchedRestaurant(JSON.parse(responseText)));}).catch((error) => {console.warn(error);});

}

and this is my call to fetchRestaurant() function inside my component:

componentDidMount(){
  this.props.fetchRestaurant();
}

Upvotes: 0

Views: 1289

Answers (1)

therewillbecode
therewillbecode

Reputation: 7180

You need to use middleware to handle the asynchronous action. One such middleware is Redux thunk.

Here is your action creator written as a Redux thunk:

export function fetchRestaurant() {
    return (dispatch) => {
       var restaurants
       fetch('https://appetizing.000webhostapp.com/connect.php')
          .then((response) => response.text())
            .then((responseText) => {
              dispatch(setFetchedRestaurant(JSON.parse(responseText)));
            })
            .catch((error) => {
               console.warn(error);
            });

    }
}

redux-thunk

Remember for this to work you will to insert redux-thunk into your middleware chain when configuring your Redux store

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

How does a Thunk Action creator work?

This single thunk action creator is an action creator that will be handled by our redux thunk middleware since it fits the signature associated with thunk action creators, that is it returns a function.

When store.dispatch is called our actions will go through the middleware chain before they reach the store. Redux Thunk is a piece of middleware that will see our action is a function and then give this function access to the stores dispatch and get state.

Here is the code inside Redux thunk that does this:

if (typeof action === 'function') {
  return action(dispatch, getState, extraArgument);
}

Okay so that is why our thunk action creator returns a function. because this function will be called by middleware and give us access to dispatch and get state meaning we can dispatch further actions at a later date.

Remember redux-thunk is not the only solution. if we wanted to dispatch promises instead of functions we could use redux-promise. However I would recommend starting with redux-thunk as this is the simplest solution.

redux-promise

An alternative method to redux thunk for handling your async Redux actions is redux-promise. Instead of action creators that return a function you can dispatch action creators that return a promise.

Here is an example:

function actionExample(payload){
    return new Promise( (resolve, reject) => {
        resolve(data); 
    });
}

You can of course combine redux-promise and redux-thunk middleware so that you can dispatch functions that when called dispatch promises

Upvotes: 3

Related Questions