Home > OS >  localStorage issue when trying to login
localStorage issue when trying to login

Time:01-02

After transferring my code into async-await, the localStorage issue happened. Can anybody tell me what is the issue and how to overcome it?

Login page code:

import React, { useState } from 'react'
import {
  CButton,
  CCard,
  CCardBody,
  CCardGroup,
  CCol,
  CContainer,
  CForm,
  CFormInput,
  CInputGroup,
  CInputGroupText,
  CRow,
} from '@coreui/react'
import CIcon from '@coreui/icons-react'
import { cilLockLocked, cilUser } from '@coreui/icons'

const Login = () => {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const authenticateUser = async () => {
    try {
      const userData = { email, password }
      const _data = await fetch('http://localhost:4000/api/v1/auth/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(userData),
      })

      if (_data.status === 200) {
        localStorage.setItem('token', _data.user.token)
      } else {
        throw new Error()
      }
    } catch (err) {
      console.error(err)
    }
  }

  return (
    <div className="bg-light min-vh-100 d-flex flex-row align-items-center">
      <CContainer>
        <CRow className="justify-content-center">
          <CCol md={8}>
            <CCardGroup>
              <CCard className="p-4">
                <CCardBody>
                  <CForm>
                    <h1>Login</h1>
                    <p className="text-medium-emphasis">Sign In to Dashboard</p>
                    <CInputGroup className="mb-3">
                      <CInputGroupText>
                        <CIcon icon={cilUser} />
                      </CInputGroupText>
                      <CFormInput
                        placeholder="Email"
                        autoComplete="email"
                        onChange={(e) => setEmail(e.target.value)}
                      />
                    </CInputGroup>
                    <CInputGroup className="mb-3">
                      <CInputGroupText>
                        <CIcon icon={cilLockLocked} />
                      </CInputGroupText>
                      <CFormInput
                        type="password"
                        placeholder="Password"
                        autoComplete="current-password"
                        onChange={(e) => setPassword(e.target.value)}
                      />
                    </CInputGroup>
                    <CRow>
                      <CCol xs={6}>
                        <CButton
                          color="primary"
                          className="px-4"
                          onClick={() => authenticateUser()}
                        >
                          Login
                        </CButton>
                      </CCol>
                      <CCol xs={6} className="text-right">
                        <CButton color="link" className="px-0">
                          Forgot password?
                        </CButton>
                      </CCol>
                    </CRow>
                  </CForm>
                </CCardBody>
              </CCard>
            </CCardGroup>
          </CCol>
        </CRow>
      </CContainer>
    </div>
  )
}

export default Login

Login details are shown in Postman:

{
    "user": {
        "token": "token here"
    }
}

Error showing in the console:

TypeError: Cannot read properties of undefined (reading 'token')
    at authenticateUser (Login.js:34)

From this method, the code is working perfectly.

fetch('http://localhost:4000/api/v1/auth/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(userData),
    })
      .then((response) => response.json())
      .then((data) => {
        localStorage.setItem('token', data.user.token)
        history.push('/dashboard')
      })
      .catch((error) => {
        console.error('Error:', error)
      })

CodePudding user response:

This doesn't have anything to do with localStorage but with the way, you are using fetch. You forgot to read the response body ...

const authenticateUser = async () => {
  try {
    const userData = { email, password }
    const response = await fetch('http://localhost:4000/api/v1/auth/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(userData),
    })

    if (response.status === 200) {
      let data = await response.json(); // <-- read json data from the response here
      localStorage.setItem('token', data.user.token)
    } else {
      throw new Error()
    }
  } catch (err) {
    console.error(err)
  }
}

CodePudding user response:

use function then in fetch and put your code there and you will put await statment before fetch like the below: check it please and let me know

  const authenticateUser = async () => {
        try {
          const userData = { email, password }
          await fetch('http://localhost:4000/api/v1/auth/login', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(userData),
          }).then(function(response){
              if (response.data.status === 200) {
            localStorage.setItem('token', response.data.user.token)
          } else {
            throw new Error()
          }
          })
    
         
        } catch (err) {
          console.error(err)
        }
      }
  • Related