1

I am coding a SPA in react.js and I am using redux-api to handle backend connection. I want to do a sync action to refresh the auth token before doing the main action; this way, every time I will do an action to the backend I will be sure that the token is valid.

const endpoints = {
 {
   url: '/some/url',
   crud:true,
   prefetch:[
     ({actions, dispatch, getState}, cb) =>{
       actions.auth_token.post(JSON.stringify({
         token: "my token",
         refreshToken: "my_refresh_token"
       }),null, (err, data) =>{
           if(err){
             // HANDLE ERROR
           }
           setToken(data)
       })
     }
   ]
 }
}

const api = reduxApi(endpoints)

How can I call the prefetch function in a sync way? So first the token refreshes and then the Action?

EDIT We can do the stuff async, the important is the final call to cb(), here is the example

const endpoints = {
 {
   url: '/some/url',
   crud:true,
   prefetch:[
     ({actions, dispatch, getState}, cb) =>{
        let mills = new Date().getTime()
        const { token, generationTime, accessTokenLife, refreshTokenLife, refreshToken } = localStorage
        // Conditions: exixts token, it is expired, refresh token is not expired
        if(token && generationTime + accessTokenLife - 500 < mills && generationTime + refreshTokenLife - 500 > mills){

        dispatch(actions.token_refresh.get(null, null, (err, data) =>{
        if(err){
           dispatch(setError(err))
        }else{
           refreshTokenData(data)
        }
        cb()
       }))    
   }else{
    cb()
  }
 }
 ]}}

const api = reduxApi(endpoints)

1 Answers1

0

You may not need to request the token every time you do an async action. In fact, I'd encourage you not to.

You can request the token when you authenticate the user and cache it using web storage. Now instead of sending a network request to retrieve the users token every time you need it, you simply check the browsers cached storage. If the token for the user exists then the user has successfully authenticated. Otherwise, the user has not logged in and you can redirect the user to the authentication page.

Since that was not actually an answer to your problem but rather a different way to solve your problem I will also answer your question in a way that is more inline with the question. You should be able to utilize promise chaining to request the user's token and then once that resolves, do any other action.

I will explain in an abstract way that is not explicity related to redux-api that you should be able to adapt to redux-api specific constructs easy enough.

const actionOne = () => {
   actions.post(myJson)
     .then(response => actionTwo(response))
     .catch(error => console.log(error))
}

An important modification you would need to make is to convert actions.auth_token.post to return a promise. Then you can chain other actions to the resolution of that promise. If you are not familiar with promises MDNs documentation is quite good. For more information on converting a function from callbacks to promises this Stack Overflow answer is quite detailed.

  • 1
    Hi! Thanks for the answer. With this example I wanted to make a SSCCE to point out the problem, in the developmente env i get the token one and refresh it before it expires. In any case i found the solution: I can use a async operation and on success or error i must call the cb() function. That's it! – Lorenzo De Francesco Aug 08 '17 at 06:47