Reputation: 2389
I'm trying to make a Mongoose query to run only once if the field inside the document hasn't been updated already, but I'm getting a bit lost with the $exist
, $update
, $ne
- I don't know what to use really.
I have the following query:
const assignPhotoCodeToModel = (modelID, photoCode) => {
const filter = { id: modelID }
const update = { photoCode: photoCode }
const options = { new: true, useFindAndModify: false }
return new Promise((resolve, reject) => {
ModelModel.findOneAndUpdate(filter, update, options)
.then((response) => {
resolve(response)
})
.catch((error) => {
reject(error)
})
})
}
But I want this to run only if the field Model.photoCode
is empty. If it already has a value, I just want it to return that value.
The problem I'm having is that every time the backend hits the route, a new photoCode gets assign to the model even if it has been already assigned. So it gets reassigned again again with a new one.
router.post(
'/payment/success',
(req, res, next) => {
...omitted_code...
photoCodeModel
.assignPhotoCodeToModel(req.body.modelId, photoCode)
... omitted_code
})
I'm writing this after trying the answers provided here. At first glance they seem to work, but now I'm getting into the error that when the Model.photoCode
already has a value in it the return of the following function:
const assignPhotoCodeToModel = (modelID, photoCode) => {
//the difference is here
const filter = { id: modelID, photoCode : null }
const update = { $set: { photoCode: photoCode } }
const options = { new: true, useFindAndModify: false }
return new Promise((resolve, reject) => {
ModelModel.findOneAndUpdate(filter, update, options)
.then((response) => {
resolve(response)
})
.catch((error) => {
reject(error)
})
})
}
returns null
, while I'm actually expecting the same model document to be returned. I'm guessing is because of the filtering? When I remove the photoCode : null
it goes back to "working", but then I'm back to the problem that photoCode
field gets populated with new values.
Basically I would like that function populates the filed photoCode
once, but every subsequent call should just bring me back the same model document.
Upvotes: 2
Views: 449
Reputation: 56
Write it in a neat asynchronous form. It will work.
const assignPhotoCodeToModel = async (modelID, photoCode) => {
const filter = { id: modelID, photoCode : null };
const update = { photoCode: photoCode };
const options = { new: true, useFindAndModify: false };
return await ModelModel.findOneAndUpdate(filter, update, options);
}
Upvotes: 1
Reputation: 3663
I think what you need is $set . And, following your logic, I think you have to query "document that doesn't have photoCode yet". It should be:
const assignPhotoCodeToModel = (modelID, photoCode) => {
//the difference is here
const filter = { id: modelID, photoCode : null }
const update = { $set: { photoCode: photoCode } }
const options = { new: true, useFindAndModify: false }
return new Promise((resolve, reject) => {
ModelModel.findOneAndUpdate(filter, update, options)
.then((response) => {
resolve(response)
})
.catch((error) => {
reject(error)
})
})
}
Upvotes: 2