Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous api calls with redux-saga

I am following redux-saga documentation on helpers, and so far it seems pretty straight forward, however I stumbled upon an issue when it comes to performing an api call (as you will see link to the docs points to such example)

There is a part Api.fetchUser that is not explained, thus I don't quiet understand if that is something we need to handle with libraries like axios or superagent? or is that something else. And are saga effects like call, put etc.. equivalents of get, post? if so, why are they named that way? Essentially I am trying to figure out a correct way to perform a simple post call to my api at url example.com/sessions and pass it data like { email: 'email', password: 'password' }

like image 226
Ilja Avatar asked Aug 05 '16 14:08

Ilja


People also ask

Is redux saga asynchronous?

Using Redux Saga to handle multiple async requestsInstead of invoking the asynchronous request directly, the method call will return only a plain object describing the operation. Redux Saga then takes care of the invocation and return the result to the generator. The same thing happens with the put method.

Can we use async await in redux saga?

You can transpile async/await into generators, but you can't do the reverse. As a userland library, redux-saga can handle asynchronous behavior in ways that async/await doesn't.

What does redux saga call do?

The redux-saga middleware takes care of executing the function call and resuming the generator with the resolved response. This allows us to easily test the Generator outside the Redux environment. Because call is just a function which returns a plain Object.


2 Answers

Api.fetchUser is a function, where should be performed api ajax call and it should return promise.

In your case, this promise should resolve user data variable.

For example:

// services/api.js export function fetchUser(userId) {   // `axios` function returns promise, you can use any ajax lib, which can   // return promise, or wrap in promise ajax call   return axios.get('/api/user/' + userId); }; 

Then is sagas:

function* fetchUserSaga(action) {   // `call` function accepts rest arguments, which will be passed to `api.fetchUser` function.   // Instructing middleware to call promise, it resolved value will be assigned to `userData` variable   const userData = yield call(api.fetchUser, action.userId);   // Instructing middleware to dispatch corresponding action.   yield put({     type: 'FETCH_USER_SUCCESS',     userData   }); } 

call, put are effects creators functions. They not have something familiar with GET or POST requests.

call function is used to create effect description, which instructs middleware to call the promise. put function creates effect, in which instructs middleware to dispatch an action to the store.

like image 109
1ven Avatar answered Sep 27 '22 19:09

1ven


Things like call, put, take, race are effects creator functions. The Api.fetchUser is a placeholder for your own function that handles API requests.

Here’s a full example of a loginSaga:

export function* loginUserSaga() {   while (true) {     const watcher = yield race({       loginUser: take(USER_LOGIN),       stop: take(LOCATION_CHANGE),     });      if (watcher.stop) break;      const {loginUser} = watcher || {};     const {username, password} = loginUser || {};     const data = {username, password};      const login = yield call(SessionService.login, data);      if (login.err === undefined || login.err === null && login.response) {       yield put(loginSuccess(login.response));     } else {       yield put(loginError({message: 'Invalid credentials. Please try again.'}));     }   } } 

In this snippet, the SessionService is a class that implements a login method which handles the HTTP request to the API. The redux-saga call will call this method and apply the data parameter to it. In the snippet above, we can then evaluate the result of the call and dispatch loginSuccess or loginError actions accordingly using put.

A side note: The snippet above is a loginSaga that continuously listens for the USER_LOGIN event, but breaks when a LOCATION_CHANGE happens. This is thanks to the race effect creator.

like image 44
VanDanic Avatar answered Sep 27 '22 20:09

VanDanic