Using findOne () and findOneById with HTTP requests (Nodejs + mongoose)

0

I'm doing a api rest where I want to do HTTP requests using Postman, specifically I want to do a search or update a mongodb document, but this must be by an id that is not the doc_id that mongo provides.

Basically what I need is for someone to "check" my code and tell me what is wrong or what is missing. Here is the same question in the stackoverflow forum in English Here

models Schema

'use strict'

 const mongoose = require('mongoose')
 const Schema   = mongoose.Schema

 const infoClientSchema = Schema ({
     idusr: String,                          /*Esto es requerido*/
     name: String,
     phone: Number,
     address: String,
     riff: String,
     state: String,
     city: String,
     email: {type: String}
})

Controller (This is the GET method I know using findById and it works)

'use strict'

 const InfoCli = require('../models/infoclient')

 function getInfoCli(req, res){
    let infocliId = req.params.infocliId

    InfoCli.findById(infocliId, (err, infocli) =>{
        if (err) return res.status(500).send({message: 'Error making 
                                                request: $(err)'})

        if (!infocli) return res.status(404).send({message: 'The client does 
                                                           not exist '})

        res.status(200).send({infoclient: infocli})     
    })
 }

Controller (This is the GET method which I thought would work using findOne)

function getInfoByUsr(req, res){
    let idusr = req.params.idusr

    InfoCli.findOne(idusr, (err, infocli) => {
        if (err) return res.status(500).send({message: 'Error making 
                                                request: $(err)'})

        if (!infocli) return res.status(404).send({message: 'The client does 
                                                           not exist '})

        res.status(200).send({infoclient: infocli})

        console.log(infocli) /*La consola no esta arrojando nada*/
    })
 }

Controller (This is the PUT method which I thought would work using findOneAndUpdate)

function updateByUsr(req, res){
    let idusr  = req.params.idusr
    let update = req.body

    InfoCli.findOneAndUpdate(idusr, update, (err, infocliUpdate) => {
        if (err) return res.status(500).send({message: 'Error making 
                                                request: $(err)'})

        if (!idusr) return res.status(404).send({message: 'The client does 
                                                           not exist '})

        res.status(200).send({infocliente: infocliUpdate})
    })
 }

Routes (I'm not 100% sure of this)

const express     = require('express')
const InfoCliCtrl = require('../controllers/infoclient')
const api         = express.Router()

api.get('/infoclient/:infocliId', InfoCliCtrl.getInfoCli) /*working*/
api.get('/infoclient/:idusr', InfoCliCtrl.getInfoByUsr)
    
asked by Rwa 14.04.2017 в 20:27
source

3 answers

1

The findOne method receives an object that will be used to find matches, as you do with find :

InfoCli.findOne({ idusr }, (err, cli) => {
  ...
});

InfoCli.findOneAndUpdate({ idusr }, req.body, (err, cli) => {

});

PD: Try to use promises instead of callbacks; this year, async/await is standardized and the frameworks will implement it gradually.

Normal promises:

InfoCli
  .findOne({ idusr })
  .then(doc) => {

  })
  .catch(err => {

  });

Using async/await :

try {
  const cli = await InfoCli.findOne({ idusr });
} catch (e) {
  // error
}
    
answered by 14.04.2017 в 20:43
1

In your code, the findOne() and findById() methods are using it correctly.

findOne()

It requires two parameters (in its most basic form), the first is an object that serves to locate the document through matches and the second is a callback that contains the possible error or user, as appropriate, which returns the consult.

findById()

It is similar, only that as the first parameter you receive the id of the document to be consulted.

For your controller corresponding to the PUT, you must bear in mind that the findOneAndUpdate() method, in the way you are using it, will return, through the callback, the corresponding document to the user WITHOUT HAVING BEEN UPDATED . Eye: This does not mean that the update has not been done.

For your method to return the document with the included updates you must add one more parameter to the query:

{new:true}

Staying as follows:

InfoCli.findOneAndUpdate(idusr, update, {new:true}, function(e, usr){
    //Aqui va el resto de tu código
});

I would recommend you read the Mongoose documentation and practice it, as well as incorporate validations in your Scheme

And as for the first answer, I agree that you should implement the use of promises or async/await , as long as you understand perfectly how the asynchrony and the use of callbacks work.

    
answered by 14.04.2017 в 21:25
0

Many thanks to all for your help, the problem was a horrible mistake on my part in the routes of the api

This way I was using two routes for the same request:

api.get('/infoclient/:infocliId', InfoCliCtrl.getInfoCli) /*working*/
api.get('/infoclient/:idusr', InfoCliCtrl.getInfoByUsr)

Of course, placing the identifier for the idusr conflicted with the ObjectId search

In this way everything is corrected:

api.get('/infoclient/idusr/:idusr', InfoCliCtrl.getInfoByUsr)
    
answered by 15.04.2017 в 22:38