3

Still getting used to this.

I have checked out questions here and here and I still feel uncomfortable about how to go about this. These are not clear from my perspective.

Basically I have clicked on the "Login" button and have requested a JWT login token and succesfully received it. What I have noticed is that I can at this point download those rarely changed lists like states or suburbs/postcodes which are large (the latter) and should be at the spa's immediate use rather than tacking it onto a call for a client.

I want to, upon successfully receiving the token immediately do an API call for those lists and store them in local storage. There is no "event" it should fire straight after a successful retreival of a JWT...

Here is the action for retreiving a JWT in react:

export const requestLoginToken = (username, password) =>
  (dispatch, getState) => {
    dispatch({type: REQUEST_LOGIN_TOKEN, payload: username})

    const payload = {
      userName: username,
      password: password,
    }

    const task = fetch('/api/jwt', {
      method: 'POST',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
    })
      .then(handleErrors)
      .then(response => response.json())
      .then(data => {
        dispatch({type: RECEIVE_LOGIN_TOKEN, payload: data})
        saveJwt(data)
      })
      .catch(error => {
        clearJwt()
        dispatch({type: ERROR_LOGIN_TOKEN, payload: error.message})
      })
    addTask(task)
    return task
  }

I beleive the place for adding a second API call would be after "saveJwt()" but how.

Do/can I send it off to another export const action/function in another part of the application?

If I write something similar to this and by putting the name of the function in with a parameter of "JWT" eg

.then(retrieveSelectData)

that it will go off to that separate folder with that export function and execute an API call at the same time applying a dispatch...and then return..

Could some one outline if this is a correct and reasonable way of making two API calls as one. I still have to get the JWT (and use it in the second) so I cant do the second call without the first.

Community
  • 1
  • 1
si2030
  • 3,895
  • 8
  • 38
  • 87

1 Answers1

1

If i understand your goal correctly, what you need here is a middleWare that will catch all actions that dispatched before the reducers catches them and can accept functions and holds a ref to the dispatcher.
Note that reducers can only accept actions that are plain objects and can't accept functions.

Enters redux-thunk, a middleware that does just that (and more) in only 11 lines of code.
It catches all actions (before the reducers) and checks to see if this action === 'function'.
If it is a function then it will call that function with dispatch as the argument.
If it's not a function it will leave it alone and let the reducers do their job.

Something like this:

function loadSomeThings() {
    return dispatch => {
        fetchFirstThingAsync.then(data => { // first API call
            dispatch({ type: 'FIRST_THING_SUCESS', data }); // you can dispatch this action if you want to let reducers take care of the first API call
            return fetchSecondThingAsync(data), // another API call with the data received from the first call that returns a promise
        })
        .then(data => {
             dispatch({ type: 'SECOND_THING_SUCESS', data }); // the reducers will handle this one as its the object they are waiting for
        });
    };
}
Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99