Andy
Andy

Reputation: 2140

Thunk + Redux (in React Native) : Can't get action to work

I'm brand new to this stack. I've seen quite a few other questions about this and have read the Thunk documentation but I can't stitch this together.

When I run the code below I get the error "Actions must be plain objects, use custom middleware for async actions" which is exactly the problem I'm trying to solve with Thunk.

My action looks like this:

src/actions/recipes.js

// this calls the API
function fetchApiGetRecipes() {
  return fetch('https://mywebsite.com/endpoint/', {
    method: 'GET',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + idToken
    }
  }).then((json) => {
    dispatch({
      type: 'RECIPES_REPLACE',
      data: json
    })

  });
}

// this is passed into my container to use to refresh the recipe list
export function getRecipes() {    
  if (Firebase === null) return () => new Promise(resolve => resolve());

  if (Firebase.auth().currentUser !== null) {
          Firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {            
            // console.log(idToken);
            return dispatch => new Promise(resolve => fetchApiGetRecipes(idToken) )                  
          }).catch(function(error) {
            // Handle error
          });

  } else {
    console.log("Null user");
  }

}

What is the correct syntax to use Thunk here and fix the error I'm getting when the app starts up?

EDIT: I create the store like this:

import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, persistCombineReducers } from 'redux-persist';
import storage from 'redux-persist/es/storage'; // default: localStorage if web, AsyncStorage if react-native
import thunk from 'redux-thunk';
import reducers from '../reducers';

// Redux Persist config
const config = {
  key: 'root',
  storage,
  blacklist: ['status'],
};

const reducer = persistCombineReducers(config, reducers);

const middleware = [thunk];

const configureStore = () => {
  const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
    compose(applyMiddleware(...middleware)),
  );

  const persistor = persistStore(
    store,
    null,
    () => { store.getState(); },
  );

  return { persistor, store };
};

export default configureStore;

Upvotes: 0

Views: 208

Answers (2)

dvvtms
dvvtms

Reputation: 627

probably you forgot pass dispatch to func args?

// you use dispatch in this func
function fetchApiGetRecipes() {...}

// you forget pass
return dispatch => new Promise(resolve => fetchApiGetRecipes(idToken) )

Upvotes: 1

yaswanth
yaswanth

Reputation: 2477

Your getRecipes function doesn't return a function in the if (Firebase.auth().currentUser !== null) clause.

You need to return a function where you are just doing

Firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {            
            // console.log(idToken);
            return dispatch => new Promise(resolve => fetchApiGetRecipes(idToken) )                  
          }).catch(function(error) {
            // Handle error
          });

The dispatch function (I assume is the intended one to return) is being returned in the then clause of the promise. That doesn't return the dispatch function to the outer method getRecipies. Hence the error

Upvotes: 1

Related Questions