sosick
sosick

Reputation: 622

Redux: async/await and handle the event

This is my first time with Redux, and i'm stuck on fetch data (and handle the event). I want to fetch data on form submit. I create code like below and now. If i get the ready to set state data object from server iw Was easier to me, but now I don't now how to the getWeather funcion and what to replace setState method. What i need to passed to reducer to get correct data?

reducer:

const initialState = {
  date: null,
  city: null,
  country: null,
  temp: null,
  temperatures: [],
  error: null,
  number: 0
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.GET_WEATHER:
      return {
        ...state
        // fetched data
      };
    default:
      return state;
  }
};

action:

export const getWeather = e => {
  return async dispatch => {
    e.preventDefault();
    const city = e.target.elements.city.value;
    let temperatures = [];
    const API_CALL = await fetch(`url${city}url`);
    const data = await API_CALL.json();

    if (!city) {
      this.setState({error: "lorem ipsum"});
      return;
    }
    try {
      for (let i = 0; i < data.list.length; i += 8) {
        temperatures.push({
          date: data.list[i].dt_txt,
          temp: Math.round(data.list[i].main.temp),
          description: data.list[i].weather[0].description
        });
      }
      this.setState({
        date: data.list[0].dt_txt,
        city: data.city.name,
        country: data.city.country,
        temp: temperatures[0].temp,
        description: data.list[0].weather[0].description,
        temperatures: temperatures,
        error: null
      });
    } catch (error) {
      this.setState({ error: "lorem ipsum" });
    }
  };
};

store:

const composeEnharcers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(reducer, composeEnharcers(applyMiddleware(thunk)));

Upvotes: 1

Views: 111

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281646

Instead of setState, you would trigger disptach with the type i.e same as the one used in reducers

export const getWeather = e => {
  return async dispatch => {
    e.preventDefault();
    const city = e.target.elements.city.value;
    let temperatures = [];
    const API_CALL = await fetch(`url${city}url`);
    const data = await API_CALL.json();

    if (!city) {
      dispatch({type: actionTypes.GET_WEATHER, error: "lorem ipsum"});
      return;
    }
    try {
      for (let i = 0; i < data.list.length; i += 8) {
        temperatures.push({
          date: data.list[i].dt_txt,
          temp: Math.round(data.list[i].main.temp),
          description: data.list[i].weather[0].description
        });
      }
      dispatch({
        type: actionTypes.GET_WEATHER,
        payload: {
          date: data.list[0].dt_txt,
          city: data.city.name,
          country: data.city.country,
          temp: temperatures[0].temp,
          description: data.list[0].weather[0].description,
          temperatures: temperatures,
          error: null
        }
      });
    } catch (error) {
      dispatch({type:actionTypes.GET_WEATHER, error: "lorem ipsum" });
    }
  };
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.GET_WEATHER:
      return {
        ...state
        ...action.payload
      };
    default:
      return state;
  }
};

Upvotes: 1

Related Questions