Reputation: 7236
I'm using this function to save to mongodb:
create(req, res, next) {
let data = req.body;
if(data) {
let newIssue = this.lib.db.model('Issues')('data');
console.log(newIssue);
newIssue.save((err, emp) => {
if(err) return next(this.RESTError('InternalServerError', err));
this.writeHAL(res, emp);
});
} else {
next(this.RESTError('InvalidArgumentError', 'No data received'));
}
}
This is my schema:
module.exports = {
"id": "Issues",
"properties": {
"issue_title": {
"type": "string",
"description": "The title of the issue"
},
"issue_number": {
"type": "string",
"description": "The issue number"
},
"issue_url": {
"type": "string",
"description": "URL of the issue"
}
}
}
My understanding of save()
is that if the document already exists in mongodb it gets updated but a new one is created if it doesn't already exist. However, each time I POST the same document, a new document is inserted rather than the existing one getting updated. I have a suspicion this is because when saving, an _id
key containing a unique ID is added to my schema making the document unique. Is this correct and if so how do I resolve this?
Additional info
I've now added a PUT. the idea is that I would do an update with {upsert:true}
. I've it partially working in that I can PUT to issue/{id} where
{id}is the mongodb
_id` and update existing documents.
This is my PUT:
update(req, res, next) {
let data = req.body;
let id = req.params.id;
if(id) {
this.lib.db.model('Issues')
.findOne({_id: id})
.exec((err, updateIssue) => {
if(err) return next(this.RESTError('InternalServerError', err));
updateIssue = Object.assign(updateIssue, data);
updateIssue.update((err, issue) => {
if(err) return next(this.RESTError('InternalServerError', err));
this.writeHAL(res, issue);
});
});
}
}
This is the routing:
controller.addAction({
'path': '/issues/{id}',
'method': 'PUT',
'summary': "UPDATES the issues's information",
'params': [swagger.pathParam('id', 'The id of the issue', 'string'),
swagger.bodyParam('issue', 'the new information to update', 'string')],
'responseClass': 'Issues',
'nickname': 'updateIssue'
}, controller.update);
I don't think I can use this for upsert as I have no _id
to begin with so can;t create the path. My other option is to use the github_id
. however any time I try to cahnge my routing path to /issues/{github_id}
or update my function with something like .findOne({github_id: id})
I get an error. I need to be able to use /issues/{github_id}
and for the check to see if the github_id
already exists. If it does, update the document, if not, create a new one.
Further info.
I've changed my update function to:
update(req, res, next) {
let data = req.body;
let id = req.params.id;
if(id) {
this.lib.db.model('Issues')
.findOne({_id: id})
.exec((err, updateIssue) => {
if(err) return next(this.RESTError('InternalServerError', err));
updateIssue = Object.assign(updateIssue, data);
updateIssue.update({_id: id}, data, (err, issue) => {
if(err) return next(this.RESTError('InternalServerError', err));
this.writeHAL(res, issue);
});
});
}
}
If I add the following console.log
's after line updateIssue.update({_id: id}, data, (err, issue) => {
:
console.log('id: ', id);
console.log('data: ', data);
console.log('err: ', err);
console.log('issue: ', issue);
I get this output:
id: 5b80307403eea4f14b06fe8c
data: { _id: '5b80307403eea4f14b06fe8c',
github_id: '347593262',
issue_title: 'test issue XY',
issue_number: '2',
issue_url: 'https://api.github.com/repos/PCTestOrg/test1/issues/2a',
__v: 0 }
err: null
issue: { n: 1, nModified: 0, ok: 1 }
I expect issue_title
to be updated from test issue X
to test issue XY
, however the update does not happen. What am I doing wrong here?
Upvotes: 0
Views: 877
Reputation: 7236
I couldn't get upsert working so ended up with the below after reading this post:
update(req, res, next) {
let data = req.body;
let id = req.params.id;
if(id) {
this.lib.db.model('Issues')
.findOne({_id: id})
.exec((err, updateIssue) => {
if(err) return next(this.RESTError('InternalServerError', err));
updateIssue = Object.assign(updateIssue, data);
updateIssue.save((err, issue) => {
if(err) return next(this.RESTError('InternalServerError', err));
this.writeHAL(res, issue);
});
});
}
else if(data) {
let newIssue = this.lib.db.model('Issues')(data);
console.log(newIssue);
newIssue.save((err, issue) => {
if(err) return next(this.RESTError('InternalServerError', err));
this.writeHAL(res, issue);
});
} else {
next(this.RESTError('InvalidArgumentError', 'No data received'));
}
}
I'm sure there is a better way to do it if anybody can show me I'd appreciate it.
Upvotes: 0
Reputation: 10111
If you want to do create or update use Update with upsert
Model.update({_id: id}, obj, {upsert: true}, function (err) {...});
Upvotes: 1