Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass parameters with redux-saga

as an exercise for react-native & redux-saga, I am trying to develop a little Weather-Application.

While fetching and presenting the data works just fine, I somehow struggle to pass a parameter from a TextInput to the final API call.

The goal for now is just to pass the cityName String to the fetchWeather function inside api.js and console.log it.

Starting by props.requestWeather(cityName) inside Main.js

I tried various things to pass the cityName via action and saga to the apiCall, only making me realize, that i was more guessing then anything else. Sadly the following research was not successful as well and so here we are.

Any ideas on how to pass the String as a parameter and/or general criticism about the following redux setup would be highly appreciated!

Dave

Main.js

//[...] setCity Name to TextInput component
const [cityName, setCityName] = useState('')   
// [...] calling the action (inside onClickHandler)
props.requestWeather() 
//[...] 
const mapStateToProps = state => ({
    weatherData: state.weatherData
});

const mapDispatchToProps = dispatch =>
    bindActionCreators({ requestWeather }, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(Main);

action.js

export const REQUEST_WEATHER = "REQUEST_WEATHER"
export const RECEIVE_WEATHER = "RECEIVE_WEATHER"

export const requestWeather = () => ({ type: REQUEST_WEATHER })
export const receiveWeather = weatherData => ({ type: RECEIVE_WEATHER, weatherData })

sagas.js

function* getWeather(action) {
  try {
    const weatherData = yield call(fetchWeather);
    yield put(receiveWeather(weatherData));
  } catch (e) {
    console.log(e);
  }
}

    
function* watchAll() {
  yield all([
    //[...]
    takeLatest(REQUEST_WEATHER, getWeather),
  ]);
}
export default watchAll;

api.js

export const fetchWeather = async () => {
  const APPID = process.env.WEATHER_API_KEY;

  try {
    let weatherData = [];
    const weather1Promise = axios(
      "https://api.openweathermap.org/data/2.5/weather?q=Rom&APPID=" + APPID
    );
    //[...]
    const [weather1, weather2, weather3] = await Promise.all([
      weather1Promise,
      weather2Promise,
      weather3Promise,
    ]);
    weatherData.push(weather1.data, weather2.data, weather3.data);
    return weatherData;
  } catch (e) {
    console.error(e);
  }
};
like image 625
dave Avatar asked Dec 11 '19 21:12

dave


1 Answers

First of all you need to modify your action to accept cityName:

export const requestWeather = (cityName) => ({ type: REQUEST_WEATHER, cityName });

Then inside sagas:

const weatherData = yield call(fetchWeather, action.cityName);

...and finally inside request:

export const fetchWeather = async (cityName) => {
  console.log(cityName); // will log entered city name
};
like image 84
kind user Avatar answered Oct 09 '22 01:10

kind user