Search code examples
javascriptreactjsredux

React Reducer get payload:undefined


I tried to get some data from googlesheets and send it to reducer. When I get data from sheets I check it in console and when I send it to reducer and check it in console it is undefined.

Reducer:

const defaultState = {
  data: [],
}

const GET_DATA_FROM_GOOGLE = "GET_DATA_FROM_GOOGLE"

export const googleDataReducer = (state = defaultState, action) => {
  switch (action.type) {
    case "GET_DATA_FROM_GOOGLE":
      console.log('1 reducer')
      console.log(action) // there are payload:undefined 
      console.log('2 reducer')
      return {
        ...state,
        data: action.payload
      }    

    default:
      return state
  }
}

export const getDataFromGoogleAction = (payload) => ({
  type: GET_DATA_FROM_GOOGLE,
  payload
})

Where I fetch data from googlesheet:

import { getDataFromGoogleAction } from "../store/googleDataReducer.js"

export const fetchData = () => {
  return function(dispatch) {
    let onlySmr fetch('https://script.google.com/macros/s/AKfycbyfcEvLSna_NbO-FDPSuo_efg7tK2uVugGDGTBqpQ1mrFvNPnqEGUFbPLgD-buhj4kT/exec') 
      .then((response) => response.json())
      .then((response) => onlySmr = response['smr']) // there are normal data 
      .then((onlySmr) => console.log(onlySmr))
      .then((onlySmr) => dispatch(getDataFromGoogleAction(onlySmr))) 
  }
}

Solution

  • The issue is in the fetchData function. The Promise chain breaks returning a defined response value, specifically in the .then-able where you try to log the value. console.log is a void return. If you want to log a value mid-stream then you still need to return it in the chain.

    Bad Code

    export const fetchData = () => {
      return function(dispatch) {
        let onlySmr fetch('https://script.google.com/macros/s/..../exec') 
          .then((response) => response.json())
          .then((response) => onlySmr = response['smr']) 
          .then((onlySmr) => console.log(onlySmr))     // <-- onlySmr not returned
          .then((onlySmr) => {
            dispatch(getDataFromGoogleAction(onlySmr)) // <-- onlySmr undefined
          });
      }
    }
    

    Good Code

    I suggest just logging onlySmr in the last .then-able right before dispatching the getDataFromGoogleAction action`.

    export const fetchData = () => dispatch => {
      fetch('https://script.google.com/macros/s/..../exec') 
        .then((response) => response.json())
        .then((data) => {
          const onlySmr = data['smr'];
          console.log(onlySmr);                       // <-- log onlySmr value
          dispatch(getDataFromGoogleAction(onlySmr)); // <-- onlySmr defined
        });
    }