Red Baron
Red Baron

Reputation: 7652

How to make an async request using redux-saga

I'm trying to make a request to get some user info with redux sagas. so far I have:

function* getUserDetails() {
  const userDetails = axios.get('http://localhost:3004/user').then(response => response)
  yield put({ type: 'USER_DATA_RECEIVED', user: userDetails})
}

function* actionWatcher() {
     yield takeLatest('GET_USER_DATA', getUserDetails)
}

export default function* rootSaga() {
   yield all([
   actionWatcher(),
   ]);
}

but when I log that out user either comes back as undefined or Promise<pending>. so I tried to add in yield call(axios stuff in here)

but that didn't seem to work either

anyone got any ideas either a) how to use call properly? and b) how to pass through a payload with the action?

Upvotes: 2

Views: 175

Answers (1)

Patrick Hund
Patrick Hund

Reputation: 20236

The correct way to use the call effect in your case would be this:

function* getUserDetails() {
  const userDetails = yield call(axios.get, 'http://localhost:3004/user');
  yield put({ type: 'USER_DATA_RECEIVED', user: userDetails})
}

The first argument for call is the function you want to call, subsequent arguments are arguments you want to pass to the called function.

Improved Version

Calls to external APIs can always go wrong, so it's a good practice to safeguard against this by wrapping a try/catch block around the Axios call.

In the catch block, you could, for example, dispatch an action that signals an error, which you can use to show an error message to the user.

function* getUserDetails() {
  let userDetails;
  try {
    userDetails = yield call(axios.get, 'http://localhost:3004/user');
  } catch (error) {
    yield put({ type: 'USER_DATA_ERROR', error });
    return;
  }
  yield put({ type: 'USER_DATA_RECEIVED', user: userDetails})
}

Upvotes: 2

Related Questions