In a React app, there are instances where `localstorage.getitem('key')` may result in returning null

I've encountered a strange issue while building a login form that sets a JWT token in localstorage. The problem arises when, despite being able to see the token in my console.log, setting localstorage.getitem('idToken') sometimes returns null (about 3 out of 5 times). This behavior becomes more prevalent when I remove the console.log(idToken) from my loginUser() function in the actions.js file. My app is constructed using React/Redux.

actions.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))
}
}

This is 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);
    });
 });

By the way, this GET request always works:

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 stuck and need some assistance! Please help me resolve this issue.

Answer №1

When working with the localStorage.setItem() method, it's important to keep in mind that it is an asynchronous task. Sometimes calling

let token = localStorage.getItem('idToken')
immediately after setting the item may result in a null value being returned. To avoid this issue, try delaying the getItem operation by using setTimeout:

setTimeout(function() {
    let token = localStorage.getItem('idToken');
    dispatch(receiveLogin(user));
}, 50);

Answer №2

To make it function correctly, ensure that your token logic (such as localStorage.getItem('idToken');) is moved within the exported function

export default (async function showResults(values, dispatch) {
  let token = localStorage.getItem('idToken');
  const AuthStr = 'Bearer '.concat(token);

  let headers ={
   headers: { 'Content-Type':'application/json','Authorization' : AuthStr 
  }
 };
 axios.post(BASE_URL + 'human/new', values, headers)...

Answer №3

It is impossible for a scenario to occur where you store a key in localstorage and then it unexpectedly returns null in the following line.

localStorage.setItem('idToken', user.token);
let token = localStorage.getItem('idToken');

This situation will only arise if the value of user.token is null.

The issue may be that your promise function is not properly passing values to the next promise as shown below:

....
.then(response =>
     // ensure response is returned to the next then function
     // this data will be passed onto the subsequent then function as parameters
     return response.json();
).then(({ user, response }) =>  {
....

Answer №4

Create a function that either returns a specific value or a default value

const [hideTyC, setHideTyC] = useState(false);

  const checkLocalStorageFlag = (): any => {
    if (
      localStorage.getItem("tyc") !== null ||
      localStorage.getItem("tyc") !== undefined
    ) {
      return localStorage.getItem("tyc") || false;
    }
  };

  useIonViewDidEnter(() => {
    hideTabBar();
    setHideTyC(checkLocalStorageFlag());
  });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Show the time in hours and minutes (00:00) while rounding off seconds to the nearest minute

I need the time to always display with leading zeros when less than 10. For example, if a task took 3 hours, 7 minutes, and 33 seconds, it should be shown as 03:08. Currently, I have the buttons disabled after they are clicked to prevent restarting the ti ...

How to Align the Button Vertically with the TextField in React Material-UI

Utilizing the Material-UI library for React, I have been working on creating a simple form with the following design: https://i.stack.imgur.com/LY3ZN.png My challenge lies in aligning the button with the TextField element. Adjusting the margin-top proper ...

Develop a plugin architecture using JavaScript and Node.js

Here is a basic implementation using node.js with express: var express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('Hello World'); }); app.listen(3000); I am interested in creatin ...

Retrieving information from a repository through a Rest API

Whenever I attempt to retrieve my data from the repository and log it in the console, the array seems to be empty. Here is a snapshot of the data repo: https://i.stack.imgur.com/ftCBm.png Here is the code snippet from server.js: import express from &apos ...

"Encountered an error: File or directory not found while attempting to export a function

src/test.js module.exports.test = function() { const { readFileSync } = require('fs'); console.log(readFileSync('test.txt', 'utf8').toString()) } index.js const { test } = require('./src/test.js'); test(); ...

Error in AWS Cloud Development Kit: Cannot access properties of undefined while trying to read 'Parameters'

I am currently utilizing aws cdk 2.132.1 to implement a basic Lambda application. Within my project, there is one stack named AllStack.ts which acts as the parent stack for all other stacks (DynamoDB, SNS, SQS, StepFunction, etc.), here is an overview: im ...

Mapping an array using getServerSideProps in NextJS - the ultimate guide!

I'm facing an issue while trying to utilize data fetched from the Twitch API in order to generate a list of streamers. However, when attempting to map the props obtained from getServerSideProps, I end up with a blank page. Interestingly, upon using co ...

Implement a unique feature for specific days using jQuery UI Datepicker with a customized class

Looking to highlight a range of days horizontally in jQuery UI Datepicker with the multiselect plugin. To achieve this, I am utilizing the :before and :after pseudoelements of the a tags. .ui-state-highlight a:before, .ui-state-highlight a:after { con ...

Is it possible for me to determine whether a javascript file has been executed?

I am currently working with an express framework on Node.js and I have a requirement to dynamically change the value (increase or decrease) of a variable in my testing module every time the module is executed. Is there a way to determine if the file has ...

Is there a way for me to extract and showcase the initial 10 items bearing a particular class name from a different html document on my homepage?

I am looking to extract a list of movies from an HTML file titled "movies.html". The structure of the file is as follows: <div class="movie">Content 1</div> <div class="movie">Content 2</div> <div class=" ...

Tips for stopping PHP echo from cutting off a JS string?

I encountered an issue with my code: <!DOCTYPE html> <html> <head> <title>Sign up page</title> <meta charset="UTF-8"/> </head> <body> <h1>Sign up page</h ...

Inadequate data being sent to the server from Angular2 post request

Currently, I have a form field whose value I am passing to a service as this.form.value. However, when I log this.form.value on the console, I see Object { email: "zxzx", password: "zxzxx" }. Despite this, when I send the same data to the service and make ...

Tips for enabling resize functionality on individual components one at a time

Check out my Codepen link for the resizable event While using Jquery UI resizable, everything is functioning correctly. However, I am now looking to have the resizable event activate one block at a time. When another block is clicked, the resizable event ...

JavaScript - issue with event relatedTarget not functioning properly when using onClick

I encountered an issue while using event.relatedTarget for onClick events, as it gives an error, but surprisingly works fine for onMouseout. Below is the code snippet causing the problem: <html> <head> <style type="text/css"> ...

The MUI makeStyles() class has been implemented, yet the styles are not being displayed when using classList.add('class-name')

Currently, I am utilizing MUI makeStyles() to create a series of CSS classes. Within these classes, I am dynamically including and excluding one specific class to my Box element during file drag-and-drop events. The class is successfully added, as I can o ...

Having trouble establishing a connection to the SQL Server database in my React application

I'm stuck trying to connect my database with my React app. I created the database using SQL in SQL Server Management Studio. I attempted to use express for the connection, but it seems like there are pieces missing in my code. Can someone guide me on ...

I'm looking to add autocomplete functionality to a text input in my project, and then retrieve and display data from a MySQL database using

Looking to enhance user experience on my form where users can select inputs. Specifically, I want to implement a feature where as the user starts typing in a text input field with data from a MYSQL database, suggestions will be displayed. The form is locat ...

Is it possible to show an image without altering the Box dimensions?

Hi there, I am currently working on designing a footer and I have encountered an issue. I want to add an image in a specific position, but when I do so, it affects the size of the box. I was wondering if there is a way to set the image as a background or b ...

serving files using express.static

I have set up express.static to serve multiple static files: app.use("/assets", express.static(process.cwd() + "/build/assets")); Most of the time, it works as expected. However, in certain cases (especially when downloading many files at once), some fil ...

Using Node.js to return JSON data containing base64 encoded images

In my database, I store all images as base64 with additional data (creation date, likes, owner, etc). I would like to create a /pictures GET endpoint that returns a JSON object containing the image data, for example: Image Data [{ "creation": 1479567 ...