How to pass parameters with redux-saga
Asked Answered
A

2

15

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);
  }
};
Angrist answered 11/12, 2019 at 21:13 Comment(0)
H
14

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
};
Handsome answered 11/12, 2019 at 21:47 Comment(1)
Thank you so much kind user! The 'action.' before cityName inside the sagas was exactly what i needed! export const requestWeather = cityName => ({ type: REQUEST_WEATHER, cityName });; just to round it up i think I need to pass cityName as a param in the action ass well.Angrist
M
0

if you are using Axios with Redux-Saga in React Application this information with sample code should be useful

In Redux saga, if you want to send AJAX request is better to use call method (built-in saga) instead of regular usage of Axios method like axios.get()

REDUX-SAGA call method

1- First Argument: pass your AJAX lib handler, for example call(Axios) and in second arument you have to pass options[] for your request



const baseApiUri = process.env.BASE_API || 'http://localhost:3030/v1';
const jwtToken = localStorage.getItem('INTERVIEW-TOKEN');

const API = axios.create({
  baseURL: baseApiUri,
  timeout: 5000,
  headers: {
    authorization: jwtToken,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
});


// your reqest options
const options = {
      method: 'post',
      url: ''localhost/3030,
      data: { name: 'hamid' },
}


// send request with SAGA
const user = yield call(API, options);



// send a request with Axios

const user = await API(options);

// or

const user = await axios.post(options)



Melia answered 4/4, 2022 at 4:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.