localstorage.getitem('key') sometimes returns null - in a react app

18,849

The localStorage.setItem() is a asynchronous task, and sometimes you run let token = localStorage.getItem('idToken') just after the setItem will fail, so you get a null, so please put the getItem operation some later, have a try, it will be different :

setTimeout(function() {
    let token = localStorage.getItem('idToken');
    dispatch(receiveLogin(user));
}, 50);
Share:
18,849
Samia Ruponti
Author by

Samia Ruponti

SOreadytohelp !! I'm now a full time front end developer! I love to write clean code, enjoy petting our office dog and I am currently learning (a bit late though) about SVGs!

Updated on June 22, 2022

Comments

  • Samia Ruponti
    Samia Ruponti almost 2 years

    this is a very weird problem! I'm trying to build a login form which sets a JWT token in localstorage. Other forms then use that token to post requests. I can see the token in my console.log just fine, but sometimes (like 3 out of 5 times), when I am setting localstorage.getitem('idToken'), it shows as null. This behavior most noticeably happens when I remove the console.log(idToken) from my loginUser() function (code in actions.js file - given below). What am I doing wrong? my app is built using React/Redux.

    action.js

    export function loginUser(creds) {
    
    const data = querystring.stringify({_username: creds.username, _password: creds.password});
    
    let config = {
        method: 'POST',
        headers: { 'Content-Type':'application/x-www-form-urlencoded' },
        body: data
    };
    
    return dispatch => {
        // We dispatch requestLogin to kickoff the call to the API
        dispatch(requestLogin(creds));
    
        return fetch(BASE_URL+'login_check', config)
            .then(response =>
                response.json().then(user => ({ user, response }))
            ).then(({ user, response }) =>  {
                if (!response.ok) {
                    // If there was a problem, we want to
                    // dispatch the error condition
                    dispatch(loginError(user.message));
                    return Promise.reject(user)
                } else {
    
                    localStorage.setItem('idToken', user.token);
                    let token = localStorage.getItem('idToken')
                    console.log(token);
                    // if I remove this log, my token is returned as null during post. 
                    dispatch(receiveLogin(user));
                }
            }).catch(err => console.log("Error: ", err))
    }
    }
    

    here's my POST request:

    import axios  from 'axios';
    import {BASE_URL} from './middleware/api';
    import {reset} from 'redux-form';
    
     let token = localStorage.getItem('idToken');
     const AuthStr = 'Bearer '.concat(token);
    
    let headers ={
    headers: { 'Content-Type':'application/json','Authorization' : AuthStr }
    };
    
    export default (async function showResults(values, dispatch) {
    console.log(AuthStr);
    axios.post(BASE_URL + 'human/new', values, headers)
        .then(function (response) {
            console.log(response);          
            alert("Your submit was successful");
            //dispatch(reset('wizard'));
        }).catch(function (error) {
            console.log(error.response);
            alert(error.response.statusText);
        });
     });
    

    This GET request works everytime, BTW:

    getHouses = (e) =>  {
        let token = localStorage.getItem('idToken') || null;
        const AuthStr = 'Bearer '.concat(token);
        axios.get(BASE_URL + 'household/list', { headers: { Authorization: AuthStr } }).then((response) =>
            {
                let myData = response.data;
    
                let list = [];
                let key =[];
                for (let i = 0; i < myData._embedded.length; i++) {
                    let embedded = myData._embedded[i];
                    list.push(embedded.friendlyName);
                    key.push(embedded.id);
                }
    
                this.setState({data: list, key: key});
    
            })
            .catch((error) => {
                console.log('error' + error);
            });
    }
    

    I'm at my wit's end! Please help!