Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return promise from React Redux Thunk

I have the next React/Redux/Thunk code:

This is my call to API:

//api.js
export const categoriesFetchData = (page, parentOf) => {
  return axios.get(
    url +
    'categories/' +
    '?parent=' +
    parentOf +
    '&limit=10' +
    '&offset=' +
    (page - 1) * 10,
  );
};

This my action (I pretend to return an axios promise from this action):

//actions.js
export const subCategoriesFetchData = (page = 1, parentOf) => {
  return dispatch => {
    dispatch(oneCategoryLoading(true));
    return api.categoriesFetchData(page, parentOf)
      .then(response => {
        dispatch(subCategoriesFetchDataSuccess(response.data.results));
        dispatch(oneCategoryLoading(false));
      })
      .catch(error => {
        console.log(error);
      });
  };
};

And in my container:

const mapDispatchToProps = dispatch => {
  return {
    fetchOneCategory: slug => {
      dispatch(fetchOneCategory(slug)).then(() => {
        console.log('working');
      });
    },

  };
};

But I get this error:

Uncaught TypeError: Cannot read property 'then' of undefined

What is wrong and how to return a promise in the container?

Thanks for your help.

like image 600
guzajj Avatar asked Jul 19 '18 18:07

guzajj


People also ask

Does Dispatch return promise?

dispatch returns something that is not a promise.

How do I use promise in Redux?

Using Redux-Promise in React AppYou can use a promise to represent a value based on the request data, either the resolved value or why the request is unresolved. JavaScript uses promises subscribed by a function, and the same function knows how to request status and resolve or reject the promise.

What is the use of createAsyncThunk in Redux?

createAsyncThunk will generate three Redux action creators using createAction : pending , fulfilled , and rejected . Each lifecycle action creator will be attached to the returned thunk action creator so that your reducer logic can reference the action types and respond to the actions when dispatched.


1 Answers

Here's how I am approaching this.

First, there are a couple of changes you need to do to your subCategoriesFetchData function:

export const subCategoriesFetchData = (page = 1, parentOf) => {
  return dispatch => {
    dispatch(oneCategoryLoading(true));

    // That's the key thing. Return a new promise, then ma
    return new Promise((resolve, reject) => {

      api.categoriesFetchData(page, parentOf)
        .then(response => {
          dispatch(subCategoriesFetchDataSuccess(response.data.results));
          dispatch(oneCategoryLoading(false));

          resolve(response); // Resolve it with whatever you need
        })
        .catch(error => {
          console.log(error);

          reject(error); // And it's good practice to reject it on error (optional)
        });
    });
  };
};

Then, here's how you can do the trick with mapDispatchToProps and then chaining .then()s:

import React from 'react';
import { connect } from 'react-redux';
import { subCategoriesFetchData } from './wherever-it-is';

class MyComponent extends React.Component {

  componentDidMount() {
    this.props.subCategoriesFetchData()
      .then( () => { console.log('it works'); })
      .catch( () => { console.log('on error'); });
  }

  render() {
    return ( <p>Whatever</p> );
  }
}

const mapDispatchToProps = { subCategoriesFetchData };

connect(null, mapDispatchToProps)(MyComponent);
like image 199
Kaloyan Kosev Avatar answered Oct 07 '22 11:10

Kaloyan Kosev