How to pass a prop through history.push() in react? - reactjs

I have a login component that has an email and password to log in. After a successful, I use this.props.history.push('/userComponent) to route a another component. At the component where it is routed should display the name of the person/user. I am trying to send as a prop but I end up getting undefined as the user component (the component to which it is routed) is not rendered. Please check the below.
export default class Login extends Component {
constructor(props) {
super(props);
this.x = '';
}
onSubmit = () => {
fetch('http://localhost:5000/api/account/')
.then(res => res.json())
.then(data => {
for (let index = 0; index < data.length; index++) {
if (userName === data[index].email && passWord === data[index].password && data[index].role === "Admin") {
console.log("login is successful");
this.x = true;
console.log('.......state after update: ' + this.x);
this.props.history.push('/userA');
return (
<div>
<UserA somePropName={data[index].userName} />
</div>
);
}
else if (userName === data[index].email && passWord === data[index].password) {
console.log("login is successful");
this.x = false;
console.log("x....... " + this.x);
this.props.history.push('/userB');
return (
<UserB somePropName={data[index].userName} />
);
}
else {
this.props.history.push('/errorPage');
}
}
});
}
render() {
return (
<div>
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required />
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" required />
<button type="submit" onClick={this.onSubmit}>Login </button>
<label>
<input type="checkbox" checked="checked" name="remember" /> Remember me
</label>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" class="cancelbtn">Cancel</button>
<span class="psw">Forgot password?</span>
</div>
</div>
);
}
}

The way you can pass properties to other component while navigation
this.props.history.push({
pathname: '/userB',
state: { title: 'Hello world' }
})
using Link
<Link to={{
pathname: '/userB',
state: { title: 'Hello...' }
}}>Click</Link>
Access like this in navigated component
this.props.location.state.title

You should render conditionally UserA or UserB in render(). Place the user related fields in the state. Something like
render() {
return (
<div>
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required />
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" required />
<button type="submit" onClick={this.onSubmit}>Login </button>
<label>
<input type="checkbox" checked="checked" name="remember" /> Remember me
</label>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" class="cancelbtn">Cancel</button>
<span class="psw">Forgot password?</span>
</div>
{this.state.isLoggedIn && this.state.isAdmin && <UserA somePropName={this.state.userName} />}
{this.state.isLoggedIn && !this.state.isAdmin && <UserB somePropName={this.state.userName} />}
</div>);
}
For the onSubmit func
onSubmit = () => {
fetch('http://localhost:5000/api/account/')
.then(res => res.json())
.then(data => {
this.props.history.push('/xxx');
this.setState({
isAdmin: data[index].role === "Admin"
isLoggedIn: userName === data[index].email && passWord === data[index].password,
userName: data[index].userName
})
})
}

Related

react hooks: remember me checkbox in Login form not working

I have a login form functional component built using react-hooks comprising of userid, password and rememberMe checkbox.
For some reason, the checkbox is not working as in, when I click on it, it does tick or untick. Which is basically its state is not changing.
userid, password and rememberMe checkbox needs to be sent to the backend. That's why I have to couple it with inputs. If it was an independent checkbox than it would have been easy.
I have handleChange() for userid, password and I have handleChechbox() for handling checkbox.
Below is the complete code.
const Login = (props) => {
const [inputs, setInputs] = useState({
userid: "",
password: "",
rememberPassword: false,
});
const [submitted, setSubmitted] = useState(false);
const { userid, password, rememberPassword } = inputs;
// reset login status
useEffect(() => {
dispatch(loginActions.logout());
}, []);
function handleChange(e) {
const { name, value } = e.target;
setInputs((inputs) => ({ ...inputs, [name]: value }));
}
function handleChechbox(e) {
const { name, value } = e.target;
console.log("eeeeee check", e.target.type);
console.log("eeeeee check", e.target.checked);
console.log("eeeeee check inputs", inputs);
console.log("eeeeee check inputs remember", inputs.rememberPassword);
if (e.target.type === "checkbox" && !e.target.checked) {
setInputs((inputs) => ({ ...inputs, [name]: "" }));
} else {
setInputs((inputs) => ({ ...inputs, [name]: value }));
}
}
function handleSubmit(e) {
e.preventDefault();
setSubmitted(true);
if (inputs) {
// get return url from location state or default to home page
const { from } = location.state || {
from: { pathname: "/admin/summary" },
};
dispatch(loginActions.login(inputs, from));
// props.history.push("/admin/summary");
}
}
return (
<div className="Login">
<div className="login-form-container">
<div className="content">
<Form className="login-form" onSubmit={handleSubmit}>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-user"></i>
</InputGroupAddon>
<input
autoFocus
type="email"
aria-label="Username"
aria-describedby="Username"
aria-invalid="false"
placeholder="Username or Email"
name="userid"
value={userid}
onChange={(event) => handleChange(event)}
className={
"form-control" + (submitted && !userid ? " is-invalid" : "")
}
/>
{submitted && !userid && (
<div className="invalid-feedback">
Username or Email is required
</div>
)}
</InputGroup>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-lock"></i>
</InputGroupAddon>
<input
type="password"
name="password"
placeholder="Password"
aria-label="password"
aria-describedby="password"
value={password}
onChange={(event) => handleChange(event)}
className={
"form-control" + (submitted && !password ? " is-invalid" : "")
}
/>
{submitted && !password && (
<div className="invalid-feedback">Password is required</div>
)}
</InputGroup>
<div className="form-actions">
<br />
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
id="rememberPassword"
name="checkbox"
checked={rememberPassword}
onChange={(event) => handleChechbox(event)}
// required
/>
<label className="form-check-label" for="rememberPassword">
Remember me
</label>
</div>
</div>
</Form>
</div>
</div>
</div>
);
};
You're reading the name attribute which is 'checkbox' not 'rememberPassword'. I'd imagine a simple console log of inputs would reveal you're setting the wrong property name.
Anyway your input is controlled, you don't need to read DOM values since you know that the value is and what it should change to.
function handleRememberMeChange(e) {
setInputs((inputs) => ({ ...inputs, rememberPassword: !inputs.rememberPassword }));
}
If you want it to work generically from an attribute then use id or change name to "rememberPassword". And use e.target.checked not e.target.value.
Also it's fine to do onChange={handleChechbox} instead of onChange={(event) => handleChechbox(event)} it's the same thing.

How can I get my component to redirect after successful action?

I am working on a sign up page and i want my user to redirect to different component after successful signup i am using redux to manage the state of the application i want my user to only go to that certain page after successful sign up. The problem is i dont know where to call it after successful action
My component
class Signup extends Component {
constructor(props) {
super(props);
this.state = {
user: {
name: '',
surname: '',
emailAddress: '',
userName: '',
password: '',
reEnterPassword: '',
isActive: true,
},
submitted: false,
error: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const { name, value } = event.target;
const { user } = this.state;
this.setState({
user: {
...user,
[name]: value
}
});
}
async handleSubmit(event) {
event.preventDefault();
this.setState({ submitted: true });
const { user } = this.state;
await store.dispatch(Register.Create(user))
this.props.history.push('/continue')
}
validateEmail = emailAddress => {
var re = /\S+#\S+\.\S+/;
return re.test(emailAddress) && <div className="help-block">Invalid emailAddress</div>;
};
render() {
const { user, submitted } = this.state;
return (
<div id="wrapper" class="signup">
<div class="signup-holder">
<div class="container">
<div class="row">
<div class="col">
<div class="img-bx" style={{backgroundImage: "url(images/img01.jpg)"}}>
</div>
</div>
<div class="col">
<form class="form" onSubmit={this.handleSubmit}>
<div class="logo">
<a href="#">
<img src="images/logo.png"/>
</a>
</div>
<div class={'form-group' + (submitted && !user.name ? ' has-error' : '')} >
<label class="form-label">First Name</label>
<input type="text" class="form-control" name = "name" value={user.name} onChange={this.handleChange} />
{submitted && !user.name &&
<div className="help-block">First Name is Required</div>
}
</div>
<div class={'form-group' + (submitted && !user.surname ? ' has-error' : '')} >
<label class="form-label">Last Name</label>
<input type="text" class="form-control" name = "surname" value={user.surname} onChange={this.handleChange} />
{submitted && !user.surname &&
<div className="help-block">Last Name is Required</div>
}
</div>
<div class={'form-group' + (submitted && !user.userName ? ' has-error' : '')} >
<label class="form-label">UserName</label>
<input type="text" class="form-control" name = "userName" value={user.userName} onChange={this.handleChange} />
{submitted && !user.userName &&
<div className="help-block">userName is Required</div>
}
</div>
<div class={'form-group' + (submitted && !user.emailAddress ? ' has-error' : '')}>
<label class="form-label">Email</label>
<input type="emailAddress" class="form-control" name="emailAddress" value={user.emailAddress} onChange={this.handleChange} />
{submitted && !user.emailAddress &&
<div className="help-block">emailAddress is Required</div>
}
</div>
<div class={'form-group' + (submitted && !user.password ? ' has-error' : '')}>
<label class="form-label">Password</label>
<input type="password" class="form-control" name= "password" value={user.password} onChange={this.handleChange} />
{submitted && !user.password &&
<div className="help-block">Password is Required</div>
}
</div>
<div class={'form-group' + (submitted && !user.reEnterPassword ? ' has-error' : '')}>
<label class="form-label">Re-Enter Password</label>
<input type="password" class="form-control" name="reEnterPassword" value={user.reEnterPassword} onChange={this.handleChange} />
{submitted && !user.reEnterPassword &&
<div className="help-block">Password is Required</div> || user.password != user.reEnterPassword &&
<div className="help-block">Password doesnot match</div>
}
</div>
<div class="form-group clearfix">
<div class="pull-left">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck" name="isActive" value={user.isActive} onChange={this.handleChange}/>
<label class="custom-control-label" for="customCheck">I agree to terms and conditions of leaty</label>
</div>
</div>
<div class="pull-right">
<Link to="/forget_password" >Forget Password ?</Link>
</div>
</div>
<div class="form-group text-center">
<button type="submit" class="btn">Sign in </button>
</div>
<div class="form-group text-center">
<p>If you are already a member Please <Link to="/login" >Sign in</Link></p>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Signup;
Action
export default class Register{
static Create(payload){
return {
type: "REGISTER",
payload:payload,
};
}
}
console.log('Success')
Reducer
import RegisterService from "../API/RegisterService";
import store from '../store/store';
const initialState = {
REGISTER:{},
loading:false,
success:{},
error:{},
};
const REGISTER_REDUCER=(state= initialState,action)=>{
const payload = action.payload;
switch(action.type){
case "REGISTER":
RegisterService.UserRegister(payload)
.then(response=>{
store.dispatch({type:'REGISTER_SUCCESS',payload:response});
})
.then(error=>{
store.dispatch({type:'REGISTER_ERROR',payload:error});
});
return {
...state,
loading:true
};
break;
case "REGISTER_SUCCESS":
console.log(payload.result.id,"ID")
localStorage.setItem('userId',JSON.stringify(payload.result.id))
return{
...state,
loading:false,
REGISTER:payload.result,
};
break;
case "REGISTER_ERROR":
return{
...state,
loading:false,
error:payload,
};
break;
default:
return state;
break;
}
}
export default REGISTER_REDUCER;
You can use <Redirect to="/your/path" /> in your render method.
Define a state like isSignedIn in your Redux State.
Connect your component to listen to that state.
Now, whenever the isSignedIn is being set to true, your component will redirect to your new path instead of rendering your signup form.
Now you can set the isSignedIn from within your Redux, right after the login is successful.
So your component should look like something like this:
import {Redirect} from 'react-router-dom';
...
class SignUp extends Component {
...
render() {
if (this.props.isSignedIn) {
return <Redirect to="/your/path" />
}
...
}
}
const mapStateToProps = state => ({
isLoggedIn: state.isSignedIn
})
export default connect(mapStateToProps)(SignUp)
And P.S: avoid calling outside functions (having side effects) in your reducer function. You can use action creators to take care of those side effects. The reducer functions should be pure and only change the state based on the function arguments, nothing more.

Storing data in multiple tables in react on the basis of role

I'm new to react and i'm building a website in which user is added on the basis of role. While adding user information, user selects a role in drop down. I have a table for Role in which only roles are kept(admin, teacher and team lead), a User table which contains user information( name, email password, etc) and a UserRole table which will have a userID and a roleID to represent which role is assigned to which user. I'm using asp.net core web-API to get and post data.
I just can't figure that out how to save roleID against the role that has been selected and userID of user in UserRole table.
can please someone help me with it?
Here is my react code of file Adduser.tsx
import * as React from 'react';
//import { ReactComponent } from '*.svg';
import '../css/form.css';
import Sidebar from '../Component/sidebar/sidebar';
const axios = require('axios');
class Adduser extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
teacherId: 0,
name: '',
email: '',
password: '',
confirmPassword: '',
gender: '',
question: [],
nameError: '',
passError: '',
emailError: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
}
componentWillMount() {
if (this.props.match.params.id != undefined) {
axios.get('https://localhost:44310/api/Users/' + this.props.match.params.id)
.then((response: any) => {
this.setState({
teacherId: response.data.teacherId,
name: response.data.name,
email: response.data.email,
password: response.data.password,
confirmPassword: response.data.confirmPassword,
gender: response.data.gender,
role: response.data.role,
question: []
});
})
.catch((error: any) => {
console.log(error);
});
}
}
handleChange = (event: any) => {
this.setState({ [event.target.name]: event.target.value }, () => this.validateName())
}
handlePasswordChange = (event: any) => {
this.setState({ [event.target.name]: event.target.value }, () => this.validatePassword())
}
validateName() {
const { name } = this.state;
this.setState(
{ nameError: name.length > 3 ? null : 'Name must contain atleast 3 characters' }
// passError: password.length > 3 || password ? null : 'Password must contain atleast 6 characters'}
)
}
validatePassword() {
const { password } = this.state;
this.setState({
passError: password.length > 6 ? null : 'Password must contain atleast 6 characters'
}
)
}
validateEmail(email: any) {
const pattern = /[a-zA-Z0-9]+[\.]?([a-zA-Z0-9]+)?[\#][a-z]{3,9}[\.][a-z]{2,5}/;
const result = pattern.test(email);
if (result === true) {
this.setState({
emailError: false,
email: email
})
} else {
this.setState({
emailError: true
})
}
// email = $('email');
// var filter = /^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
// if (filter.test(email.value)) {
// // Yay! valid
// return '';
// }
// else
// return 'invalid email';
}
handleSubmit(event: any) {
event.preventDefault();
if (this.props.match.params.id != undefined) {
const { password, confirmPassword } = this.state
if (password !== confirmPassword) {
alert('passwords do not match')
}
else {
axios.put(`https://localhost:44310/api/Users/${this.props.match.params.id}`, this.state)
.then((response: any) => {
this.props.history.push('/');
})
.catch(function (error: any) {
console.log(error);
});
}
} else {
const { password, confirmPassword, name } = this.state
if (password !== confirmPassword) {
alert('passwords do not match')
}
else {
axios.post('https://localhost:44310/api/Users/', this.state)
.then((response: any) => {
console.log(response);
alert('User has been added successfully')
})
.catch(function (error: any) {
console.log(error);
alert('Sorry! Your request can not be processed at the moment')
});
}
}
}
render() {
return (
<div className="row">
<div className=" col-lg-2">
<Sidebar />
</div>
<div className="col-lg-10">
<div className="content" >
<div className="container-fluid">
<div className="row" >
<div className="col-lg-3"> </div>
<div className="col-lg-6" style={{ paddingTop: "30px" }}>
<div id="ui">
{this.props.match.params.id != undefined ? <h1 style={{ marginTop: "15px" }}>EDIT ACCOUNT</h1> : <h1 style={{ marginTop: "15px" }}>ADD ACCOUNT</h1>}
<form className="form-group" method="post" onSubmit={this.handleSubmit} autoComplete="off">
<label> Name:</label>
<div className="name">
<input type="text"
onChange={this.handleChange}
name="name"
value={this.state.name}
className={`form-control ${this.state.nameError ? 'is-invalid' : ''}`}
placeholder="Enter username " required
onBlur={this.validateName.bind(this)} />
<div className="invalid-feedback">Name must be longer than 3 characters</div>
</div>
<br />
<label> Email:</label>
<div className="mail">
<input type="email" name="email" value={this.state.email} onChange={this.handleChange} className="form-control" placeholder="Enter E-mail" required />
<div className="invalid-feedback">Email is invalid</div>
</div>
<br />
<div className="row">
<div className="col-lg-6">
<label> Password:</label>
<div className="pass">
<input type="password" name="password" value={this.state.password} onChange={this.handlePasswordChange} className={`form-control ${this.state.passError ? 'is-invalid' : ''}`} id="pwd" placeholder="Enter password" required onBlur={this.validatePassword.bind(this)} />
<div className="invalid-feedback">Password must be longer than 6 characters</div>
</div>
</div>
<div className="col-lg-6">
<label> Re-type Password:</label>
<div className="pass1">
<input type="password" name="confirmPassword" value={this.state.pass1} onChange={this.handleChange} className="form-control" id="pwd1" placeholder="Re-type password" required />
</div>
</div>
<br />
<div className="col-lg-12">
<select className="form-control" name="gender" value={this.state.gender} onChange={this.handleChange} id="sel" style={{ marginTop: "35px" }} required>
<option>Choose Gender</option>
<option>Male</option>
<option>Female</option>
</select>
</div>
<br />
<div className="col-lg-12">
<select className="form-control" name="role" value={this.state.role} onChange={this.handleChange} id="sel" style={{ marginTop: "35px" }} required>
<option>Role</option>
<option>Admin</option>
<option>Teacher</option>
<option>TeamLead</option>
</select>
</div>
<br />
<div className="col-lg-12">
{/* <Link className="nav-link" to="/"> */}
<input type="submit" name="submit" value="submit" className="btn btn-primary btn-block btn-lg" style={{ marginTop: "20px" }} />
{/* </Link> */}
</div>
</div>
</form>
</div>
</div>
<div className="col-lg-3"></div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Adduser;

How can I pass data using <Redirect> in react router v4?

The situation is that I use axios gain data from back-end and I want to redirect from current page to another page as well as passing some data.
How can I pass data when I use <Redirect> to redirect?
I am using code like below, and I can't get 'profile' at the destination page. No matter, this.props or this.state
I understand that using react-router-redux is a better choice.
import React, { Component } from 'react'
import axios from 'axios'
import { Redirect } from 'react-router'
export default class Login extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
emailError: 'Please fill in email',
password: '',
passwordError: 'Please fill in password',
redirect: false,
profile: ''
}
this.handleEmail = (e) => {
var email = e.target.value
var emailError = ''
if (email === null)
emailError = 'Please fill in email'
this.setState({
email: email,
emailError: emailError
})
}
this.handlePassword = (e) => {
var password = e.target.value
var passwordError = ''
if (password === null)
passwordError = 'Please fill in password'
this.setState({
password: password,
passwordError: passwordError
})
}
this.handleSubmit = (e) => {
e.preventDefault()
if (this.state.emailError)
alert(this.state.emailError)
else if (this.state.passwordError)
alert(this.state.passwordError)
else {
axios.post('/user/login', {
email: this.state.email,
password: this.state.password
}).then(response => {
if (response.data !== 'fail') {
this.setState({
redirect: true,
profile: response.data
})
}
})
}
}
}
render() {
const { redirect, profile } = this.state
if (redirect)
return (<Redirect to={{
pathname: '/user/profile',
state: { referrer: this.state.profile }
}} />)
return (
<div className="content user">
<div className="container">
<div className="row">
<div className="col-xs-12">
<h1>Log In Your Tutor Profile</h1>
<form role="form" noValidate>
<div className="row">
<div className="col-xs-12">
<label htmlFor="email">Email</label>
<div className="form-group">
<input id="email" type="text" className="form-control" value={this.state.email} onChange={this.handleEmail} name="email" required/>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-12">
<label htmlFor="password">Password</label>
<div className="form-group">
<input id="password" type="password" className="form-control" value={this.state.password} onChange={this.handlePassword} name="password" required/>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-12">
<div className="form-group">
<button className="btn btn-primary submit" onClick={this.handleSubmit}>LOG IN YOUR PROFILE</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
)
}
}
The way you are passing your state to the Redirect is correct, the only place the problem should be is how you are accessing it. State can be accessed like this.props.location.state. However if you directly route to the path then state won't we available so you need to add a check
Access your state like
this.props.location.state && this.props.location.state.referrer

Unable to type in input after adding value in React Js

I have tried with the following code with react js
import React, { Component } from 'react';
import Sidebar from './../Sidebar';
import Header from './../Header';
import {get_profile} from './../services/Services';
import $ from 'jquery';
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = { userDetails: '' } ;
}
componentWillMount() {
$(window).scrollTop(0)
console.log('sdfds')
get_profile().then((response) => {
var userResults = $.parseJSON(response.text);
this.setState({ userDetails: userResults.response });
console.log(userResults);
}).catch((error) => {
//alert(error)
console.log(error);
});
}
handleChange(event) {
console.log(event.target.id)
this.setState({[event.target.name]: event.target.value});
}
render() {
return (
<div className="admin-panel">
<Sidebar />
<Header />
<div className="main-content">
<div className="contents">
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h2 className="page-title">Profile</h2>
<div className="form-group">
<label >First Name</label>
<input type="text" id="firstName" className="form-control" value={this.state.userDetails.firstName} />
</div>
<div className="form-group">
<label >Last Name</label>
<input type="text" id="lastName" className="form-control" value={this.state.userDetails.lastName} />
</div>
<div className="form-group">
<label >Email</label>
<input type="text" id="email" name="email" className="form-control" value={this.state.userDetails.email} />
</div>
<button type="button" className="btn btn-squared btn-success margin-inline" onClick={(e)=> {this.profileUpdate()}}>Update</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
After fetching the results i'm unable to edit the input box value. I have tried with defaultValue but that also not working for me. I'm struck with this issue, Kindly help me to solve the issue.
Just pass an onChange handler to the input which will update the value of the corresponding key of userDetails like this:
<input
...
value={this.state.userDetails.firstName}
onChange={this.onChange}
/>
onChange(e) {
this.setState((previousState) => {
const userDetails = previousState.userDetails
return { userDetails: {...userDetails, firstName: e.target.value} }
})
}
or you can write a common onChange function like this:
<input
...
value={this.state.userDetails.firstName}
onChange={(e) => {this.onChange(e.target.value, 'firstName')}}
/>
<input
...
value={this.state.userDetails.lastName}
onChange={(e) => {this.onChange(e.target.value, 'lastName')}}
/>
<input
...
value={this.state.userDetails.email}
onChange={(e) => {this.onChange(e.target.value, 'email')}}
/>
onChange(value, key) {
this.setState((previousState) => {
const userDetails = previousState.userDetails
return { userDetails: {...userDetails, [key]: value} }
})
}

Resources