Home > database >  'return res.json' isn't stopping my request as expected?
'return res.json' isn't stopping my request as expected?

Time:10-15

I created some sample code to demonstrate my issue on a smaller scale. I would like a solution that doesn't involve adding 'unique: true' to my model, if possible, because I seem to run into similar problems in many different scenarios:

const express = require('express')
const mongoose = require('mongoose')
const app = express()
const PORT = 6000
app.use(express.json())


// Initializing mongoose model and connection
const SampleSchema = mongoose.Schema({
    username: String,
    password: String
})
const Sample = mongoose.model('sample', SampleSchema)
mongoose.connect('mongodb://localhost/testdatabase', {
    useNewUrlParser: true,
    useUnifiedTopology: true
})


// Running my post request
app.post('/api', async (req, res) => {
    await Sample.findOne({
        username: req.body.username
    }).then(data => {
        if(data) {
            console.log(data)
            return res.json('This user already exists in my database')
        }
    })
    await Sample.create({
        username: req.body.username,
        password: req.body.password
    })
    return res.json('User created')
})


app.listen(PORT, () => {
    console.log('Server running on 6000')
})

Here is my request and database the first time I send a request: image image

This is as intended. However, if I send the same request a second time: image image

I want the code to stop on the first 'res.json' if that line of code is executed - basically, in this example I don't want to create a new Sample if one with the same username already exists. I do realize that in this case I can approach the issue differently to solve the problem, but I want to know why my 'Sample.create' line runs, and if there's a way to prevent it from running aside from the aforementioned method.

CodePudding user response:

This is because the .then callback executes after the enclosing function has already finished. In this code here:

    await Sample.findOne({
        username: req.body.username
    }).then(data => {
        if(data) {
            console.log(data)
            return res.json('This user already exists in my database')
        }
    })

The function being returned from is the data => ... arrow function passed to .then, not the enclosing request handler, so it doesn't prevent subsequent code from executing.

You want to rewrite that bit to use async/await syntax as well:

const data = await Sample.findOne({
    username: req.body.username
})

if(data) {
    console.log(data)
    return res.json('This user already exists in my database')
}

You might want to read up a bit on async/await and Promises in general-- asynchronous code can be quite confusing at first! https://developers.google.com/web/fundamentals/primers/async-functions

  • Related