sherpaurgen
sherpaurgen

Reputation: 3274

Find if item exist in database

i was following some react/express tutorials. im confused with code below in contacts.js file

 if (!contact) {
 return res.status(404).json({ msg: "Contact not found" })
        }

Is above code necessary ? or whats is there better way to catch if the contact doesn't exist in mongodb ?

when i do put request from postman with invalid id for example

localhost:44022/api/contacts/<invalid ID>

the execution never reach if (!contact) part. if i console log the catch(err) section i get something below

CastError: Cast to ObjectId failed for value "bcvbxcxc" at path "_id" for model "contact"
    at model.Query.exec (/Users/becker/Desktop/RJS/ckeeper/node_modules/mongoose/lib/query.js:4380:21)
    at model.Query.Query.then (/Users/becker/Desktop/RJS/ckeeper/node_modules/mongoose/lib/query.js:4472:15)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  messageFormat: undefined,
  stringValue: '"bcvbxcxc"',
  kind: 'ObjectId',
  value: 'bcvbxcxc',
  path: '_id',
  reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
      at new ObjectID (/Users/becker/Desktop/RJS/ckeeper/node_modules/bson/lib/bson/objectid.js:59:11)

contacts.js

router.put('/:id', auth, async (req, res) => {
 const { name, email, phone, type } = req.body;
 const contactFields = {};
 if (name) contactFields.name = name;
 if (email) contactFields.email = email;
 if (phone) contactFields.phone = phone
 if (type) contactFields.type = type;
 try {
 let contact = await Contact.findById(req.params.id);

 if (!contact) {
 return res.status(404).json({ msg: "Contact not found" })
        }

//makesure contact belongs to right user
 if (contact.user.toString() != req.user.id) {
 return res.status(401).json({ msg: 'Not authorized' })
        }
 contact = await Contact.findByIdAndUpdate(req.params.id, { $set: contactFields }, { new: true })
 res.json(contact)
    }
 catch (err) {
 console.log("reached error, contact not found")
 console.error(err)
 res.status(500).send(err)
    }

});

Contacts.js model

const mongoose = require('mongoose');
const ContactSchema = mongoose.Schema({
 user: {
 type: mongoose.Schema.Types.ObjectId,
 ref: 'users'
    },
 name: {
 type: String,
 required: true
    },
 email: {
 type: String,
 required: true,
    },
 phone: {
 type: String
    },
 type: {
 type: String,
 default: 'personal'
    },
 date: {
 type: Date,
 default: Date.now

    }
});
module.exports = mongoose.model('contact', ContactSchema)

Upvotes: 0

Views: 78

Answers (1)

Basheer Kharoti
Basheer Kharoti

Reputation: 4302

The reason for not executing the if(!contact) condition upon exception is because catch block will be called and further execution in the try block is halted. You should rather wrap each db call in its own try catch block. Something like:

 let contact;
 try {
   contact = await Contact.findById(req.params.id);
 } catch(err) {
   console.log('Some db operations failed due to reason', err);
   return res.status(500).json({ msg: "DB operations failed or whatever message" })
 }

 if (!contact) {
   return res.status(404).json({ msg: "Contact not found" })
 }
 

//makesure contact belongs to right user
 if (contact.user.toString() != req.user.id) {
   return res.status(401).json({ msg: 'Not authorized' })
 }
 try {
 contact = await Contact.findByIdAndUpdate(req.params.id, { $set: contactFields }, { new: true })
 return res.json(contact)
    }
 catch (err) {
  console.log("db update operations failed")
  console.error(err)
  res.status(500).send(err)
 }

Upvotes: 1

Related Questions