Updating model data with Schema.pre('save') and http.request calls

381 wyświetleń
Przejdź do pierwszej nieodczytanej wiadomości

Sebastien Couture

nieprzeczytany,
12 mar 2015, 07:22:0412.03.2015
do keyst...@googlegroups.com
Hello to all! 

Total newbie here with intermediate JS experience (although I haven't coded in a few years) and learning Node by building a Keynote site. I have a problem I'm trying to solve in an efficient way and hoping someone here can shed some light. 

I would like to implement a Schema.pre save middleware to update data in my model when I save an item. The middleware should grab a field in my model, make an external API call with that field as a parameter and use part of the response to update an other field in the model. Pretty easy right? 

Here's where it gets somewhat tricky. The external API call is meant to create a new item on the external service. For that to happen, a label parameter needs to be supplied. If it succeeds, it returns the status code 200 and the newly created item in JSON format. If the item already exists however (which may sometimes happen), it returns a 404. Getting an already created item requires a different method call.

Here is what I was able to come up with:

Model.schema.pre('save', function(next) {
var model = this;
function logError(err) {
console.log(err)
}
function saveValue(chunk) {
var obj = JSON.parse(chunk)
if(obj.status == 'success') {
console.log(obj);
model.otherItem = obj.data.value;
}
}

if (model.item) {
var domain = 'domain',
port = 80,
label = 'MY_LABEL_' + model.item,
pathNew = '/api/new?label=' + label + '&api_key=' + process.env.API_KEY,
pathGet = '/api/get?label=' + label + '&api_key=' + process.env.API_KEY,
method = 'GET';

http.request({
host: domain,
port: port,
path: pathNew,
method: method
}, function(res) {

res.setEncoding('utf8');
if( res.statusCode == '404') {
http.request({
host: domain,
port: port,
path: pathGet,
method: method
}, function(res2) {
res2.setEncoding('utf8');
res2.on('data', saveValue);
}).on('error', logError).end();
}

res.on('data', saveValue);

}).on('error', logError).end();

}
next();

});

I have 2 questions about this. 

1. How can I get this to work? The console.log() inside saveValue() gets executed but model.otherValue never gets updated.
2. Is there a better way to make these http.request calls. It seems a bit messy and inefficient like this.

Your help is greatly appreciated. I plan to contribute in my own little way by making this project open source and available for others as an example.

Cheers!

Martin Smola

nieprzeczytany,
27 mar 2015, 12:54:5327.03.2015
do keyst...@googlegroups.com
Your problem is that you call next(); before callback of request is called.
Make sure you call the next() after you assign new value to model.otherItem
Odpowiedz wszystkim
Odpowiedz autorowi
Przekaż
Nowe wiadomości: 0