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