Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Axios request works only on second request

I am building a user login system and currently the way I have it set up, the user types in their email and password and then that information is sent to my server to be checked if accurate. If it is, I create a JWT token and send it back along with the mongodb _id of the user, I then in another request use the mongodb _id of the user from the first request to retrieve all the information (blogs in this case) associated with their mognodb _id. All of this works except for the issue I am running into is the axios request does not work the first time. So I have to hit submit to log in for an error to occur TypeError: Cannot read properties of undefined (reading 'data') and then when I hit submit again it works. I believe the problem is getBasic not getting set before the rest of the code runs on the first attempt, and on the second attempt it is already defined. I am not sure how I can fix this without maybe a manual timer before I do the getBasic.data.map, but I know there must be a better way to fix this.

And just to add this is just me trying to test this concept so I understand later things like bcrypt will need to be added to the password instead of plaintext in the database, etc.

Frontend:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 function Login() {
    
    const [user, setUser] = useState()
    const [getBasic, setGetBasic] = useState()

    const [Item, setItem] = useState({
        email: '',
        password: ''
    });

    async function fetchData() {
        const sentItem = {
            user: user.data.user._id,
        }

        await axios.post('http://localhost:3001/api', sentItem)
            .then(result => setGetBasic(result))
    }



    const loginFunc = async () => {
        const checkUser = {
            email: Item.email,
            password: Item.password
        }

        await axios.post('http://localhost:3001/api/login', checkUser)
            .then(result => setUser(result))
            .then(fetchData())  
    }







    if (user && getBasic) {

        localStorage.setItem('key', JSON.stringify(user.data.token))
        console.log(localStorage.getItem('key'))

        return (
            <div>
                <div>
                    <input onChange={handleChange} name="email" value={Item.email} placeholder="email" />
                    <input onChange={handleChange} name="password" value={Item.password} placeholder="password" />
                    <button onClick={loginFunc}>Submit</button>

                </div>


                {
                    getBasic.data.map(({ text, _id, }, i) => {
                        return (
                            <div>
                                <p>{_id}</p>
                                <p>{text}</p>
                            </div>
                        );
                    })
                }   
        )
    }
    return (

        <div>

            <input onChange={handleChange} name="email" value={Item.email} placeholder="email" />
            <input onChange={handleChange} name="password" value={Item.password} placeholder="password" />
            <button onClick={loginFunc}>Submit</button>

        </div>
    )
}

export default Login

Server:

app.post('/api/login', async (req, res) => {


    const user1 = await User.findOne({ email: req.body.email, password: req.body.password })

    if (user1) {
        const payload = { name: req.body.name, email: req.body.email };
        const token = jwt.sign(payload, private_key, { expiresIn: '200s' });
        console.log('correct login')
        res.status(200).send({ auth: true, token: true, user: user1 })

    } else {
        console.log('incorrect login')
    }

})


app.post('/api', async (req, res) => {

    Blog.find({ user: req.body.user }, function (err, result) {
        if (err) {
            console.log(err)
        } else {
            res.send(result)
        }
    })

})

>Solution :

While nature of React.useState is asynchronous, and changes will not be reflected immediately, closures take their role in situations like this, as pointed out in link in below.

More details provided here – The useState set method is not reflecting a change immediately

As stated in error from your example, cannot read data of undefined – meaning user is undefined, and you try to access to user.data which leads to error.

const sentItem = {
    user: user.data.user._id,
}

Instead of

await axios.post('http://localhost:3001/api/login', checkUser)
            .then(result => setUser(result))
            .then(fetchData())  

why don’t you try this (remove fetchData function if not reused on other places…):

const result = await axios.post('http://localhost:3001/api/login', checkUser);
const sentItem = {
   user: result.data.user._id,
}
axios.post('http://localhost:3001/api', sentItem)
        .then(result => setGetBasic(result));

setUser(result);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading