'TypeError: Cannot read properties of null (reading 'username')
I am facing when trying to use local storage in my project. I have been trying to sign in and set the state for my both username and password. I am using two states instead of one and trying save the data in local storage using this approach.I have been attempting to sign in and set the state for my both username and password phrase. I'm utilizing two states rather than one and attempting save the information in neighborhood capacity utilizing this methodology.
Thanks in advance.
import React, { Component } from "react";
import { Row, Col, Input, Button, Alert, Container, Label } from "reactstrap";
// Redux
import { connect } from "react-redux";
import { withRouter, Link } from "react-router-dom";
// availity-reactstrap-validation
import { AvForm, AvField } from "availity-reactstrap-validation";
// actions
import { checkLogin, apiError } from "../../store/actions";
import { loginAction } from "../../redux/actions/authActions";
// import images
import logodark from "../../assets/images/logo-dark.png";
import logolight from "../../assets/images/logo-light.png";
class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: "[email protected]",
password: "12345678",
user: {},
};
this.handleSubmit = this.handleSubmit.bind(this);
}
async handleSubmit(event, values) {
this.props.checkLogin(values, this.props.history);
if (this.username && this.password) {
// let action = await this.props.loginAction(
// {
// username: this.username,
// password: this.password,
// },
// () => {
// this.props.history.push({
// pathname: "/dashboard",
// });
// }
// );
let action = await this.props.loginAction(values, () => {
this.props.history.push({
pathname: "/dashboard",
});
});
}
}
updateUser = (username, password) => {
localStorage.setItem("user", JSON.stringify(username, password));
this.setState({ username: username, password: password });
};
componentDidMount() {
this.setState({
// set username and password from local storage
username: JSON.parse(localStorage.getItem("user")).username,
password: JSON.parse(localStorage.getItem("user")).password,
});
this.props.apiError("");
document.body.classList.add("auth-body-bg");
}
componentWillUnmount() {
document.body.classList.remove("auth-body-bg");
}
render() {
return (
<React.Fragment>
<div>
<Container fluid className="p-0">
<Row className="g-0">
<Col lg={4}>
<div className="authentication-page-content p-4 d-flex align-items-center min-vh-100">
<div className="w-100">
<Row className="justify-content-center">
<Col lg={9}>
<div>
<div className="text-center">
<div>
<Link to="/" class="">
<img
src={logodark}
alt=""
height="20"
class="auth-logo logo-dark mx-auto"
/>
<img
src={logolight}
alt=""
height="20"
class="auth-logo logo-light mx-auto"
/>
</Link>
</div>
<h4 className="font-size-18 mt-4">
Welcome Back !
</h4>
{/* <p className="text-muted">Sign in to continue to Nazox.</p> */}
</div>
{/* {this.props.loginError && this.props.loginError ? <Alert color="danger">{this.props.loginError}</Alert> : null} */}
<div className="p-2 mt-5">
<AvForm
className="form-horizontal"
onValidSubmit={this.handleSubmit}
>
<div className="auth-form-group-custom mb-4">
<i className="ri-user-2-line auti-custom-input-icon"></i>
<Label htmlFor="username">Email</Label>
<AvField
name="username"
value={this.state.username}
type="text"
className="form-control"
id="username"
validate={{ email: true, required: true }}
placeholder="Enter username"
/>
</div>
<div className="auth-form-group-custom mb-4">
<i className="ri-lock-2-line auti-custom-input-icon"></i>
<Label htmlFor="userpassword">Password</Label>
<AvField
name="password"
value={this.state.password}
type="password"
className="form-control"
id="userpassword"
placeholder="Enter password"
/>
</div>
{/* <div className="form-check">
<Input type="checkbox" className="form-check-input" id="customControlInline" />
<Label className="form-check-label" htmlFor="customControlInline">Remember me</Label>
</div> */}
<div className="mt-4 text-center">
<Button
color="primary"
className="w-md waves-effect waves-light"
type="submit"
>
Log In
</Button>
</div>
{/* <div className="mt-4 text-center">
<Link to="/forgot-password" className="text-muted"><i className="mdi mdi-lock me-1"></i> Forgot your password?</Link>
</div> */}
</AvForm>
</div>
<div className="mt-5 text-center">
<p>
Don't have an account ?{" "}
<Link
to="/register"
className="fw-medium text-primary"
>
{" "}
Register{" "}
</Link>{" "}
</p>
{/* <p>© 2021 Nazox. Crafted with <i className="mdi mdi-heart text-danger"></i> by Themesdesign</p> */}
</div>
</div>
</Col>
</Row>
</div>
</div>
</Col>
<Col lg={8}>
<div className="authentication-bg">
<div className="bg-overlay"></div>
</div>
</Col>
</Row>
</Container>
</div>
</React.Fragment>
);
}
}
const mapStatetoProps = (state) => {
const { loginError } = state.Login;
return { loginError };
};
export default withRouter(
connect(mapStatetoProps, { checkLogin, apiError, loginAction })(Login)
);
Solution 1:[1]
I think currently you are storing 2 items in one string so for example:
// if you try to save such data
const username = 'admin';
const password = '123';
// below code will return this value: "'admin'"
localStorage.setItem('user', JSON.stringify(username, password));
So, your localStorage value under key 'user' is not an object, and you cannot access .username and .password keys. You can try to store username and password under separated keys or as one object:
If you are not sure your data exists before saving in local storage you can try to save some weird message in LocalStorage (just for debugging) once you make sure you are saving your data correctly then you can get rid of this
// Example 1
const username1 = null;
const password1 = '123';
localStorage.setItem('username', username1 ?? `DOESN'T EXISTS YET`);
localStorage.setItem('password', password1 ?? `DOESN'T EXISTS YET`);
console.log('USERNAME:', localStorage.getItem('username'));
console.log('PASSWORD:', localStorage.getItem('password'));
// Example 2
const username2 = 'admin';
const password2 = null;
localStorage.setItem('username-password', JSON.stringify({
username: username2 ?? `DOESN'T EXISTS YET`,
password: password2 ?? `DOESN'T EXISTS YET`
}));
console.log('USERNAME && PASSWORD', JSON.parse(localStorage.getItem('username-password')));
If you are not familiar with ?? operator, you can check this link: Nullish coalescing operator (??)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

