0

Hi i am using redux saga generator function. The purpose of this function is login the user, according to the type of user. Here i am checking if the user of any specific type then, according to that i am redirecting the user to the specific route.My question is before dispatching this action yield put(loginSuccess(response)) , i want to store token in localstorage ,as i tried this way but storing is taking some time. How can i fix this problem, or there any way to use promises here or any other better solution to fix this problem

function* login(obj) {
  const res = yield call(login, obj)
  if (res.data.token) {
    localStorage.setItem('token', res.data.token)
    yield put(Success(res))
    if (res.data.isAdmin == true) {
      history.push('/admin')
    } else if (res.data.userType == 'student') {
      history.push('/student')
    }
  } else {
    yield put(Error(res.message))
  }
}
Martin Kadlec
  • 4,702
  • 2
  • 20
  • 33
Wani
  • 61
  • 2
  • 9

1 Answers1

0

Technically, localStorage should be synchronous and so you shouldn't have to wait in any way to read the data later. However, users report that is not always the case as can be seen in comments on answer for this SO question: Is HTML5 localStorage asynchronous?

Copying from the other answer there, this is probably the root cause of the problem:

This specification does not require that the above methods wait until the data has been physically written to disk. Only consistency in what different scripts accessing the same underlying list of key/value pairs see is required.

Unfortunately, this seems to introduce a race condition where sometimes the data won't be stored yet when you try to read them in the same tick as when you stored them.

If you also run into this issue, adding yield delay(0) after the localStorage line should do the trick.


Another way to fix this to get around an arbitrary delay would be to introduce a layer of abstraction on top of localStorage where on write you would save the data both to localSotrage and in-memory and on read you would use the memory storage instead - however this can get quite complex once you introduce multiple opened tabs/windows into the equation, because then you need to listen to storage events and do proper two-way synchronization between localStorage and memory.

Google reveled some existing libs out there that already do this for you: https://github.com/nbubna/store (more complex but more robust and user tested) https://github.com/matthew-andrews/superstore-sync (lightweight, but not used by many people)

Martin Kadlec
  • 4,702
  • 2
  • 20
  • 33