Reputation: 13
I'm making a call to the Amazon product API using aws-lib npm package. I'm trying to get the result of that call and then save that information into my database, the problem I keep running into is that if I make a call with lots of parameters when I try to set the result of the call to the product I get undefined because the API call hasn't been returned completely yet. I've attempted to use callbacks and promises to make sure the API result is completely returned before I do anything else but I can't get it to work.
This the the current state of my code
var aws = require('aws-lib');
var host = "http://webservices.amazon.co.uk/onca/xml"
var prodAdvOptions = {
host: "webservices.amazon.co.uk",
region: "UK"
};
// provide credentials
var prodAdv = aws.createProdAdvClient(myKey, myPass, myId, prodAdvOptions);
.post(function(req, res) {
// Options for the Amazon API
var options = {
ItemId: req.body.itemId,
ResponseGroup: "OfferFull, ItemAttributes",
Condition: "New",
MerchantId: "Amazon"
}
getInfo(options, saveProduct, res);
}
function getInfo(options, saveProduct, res){
// Make call to the API
prodAdv.call("ItemLookup", options, function(err, result) {
//create new product
var product = new Product();
product.name = result.name
//assign lots more things to the product - these will return undefined which is the problem
saveProduct(product);
})
};
function saveProduct(product){
// save product to the database
};
This is the call to the API using aws-lib
exports.init = init;
function init(genericAWSClient) {
return createProdAdvClient;
function createProdAdvClient(accessKeyId, secretAccessKey, associateTag, options) {
options = options || {};
var client = genericAWSClient({
host: options.host || "ecs.amazonaws.com",
path: options.path || "/onca/xml",
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
secure: options.secure
});
return {
client: client,
call: call
};
function call(action, query, callback) {
query["Operation"] = action
query["Service"] = "AWSECommerceService"
query["Version"] = options.version || '2009-10-01'
query["AssociateTag"] = associateTag;
query["Region"] = options.region || "US"
return client.call(action, query, callback);
}
}
}
I think I'm not using callbacks correctly or need another one for assigning the result to the product but can't work out where I'm going wrong.
Thanks for the help I've been banging my head against this for 2 days.
Upvotes: 1
Views: 132
Reputation: 55962
It might be easier to see what's going on initially without promises, then use promises after an understanding has been reached.
One option for the flow of the program is:
post
callback is calledgetInfo
is calledprodAdv
is called which is ansynchronous, which means a callback will have to be provided with what to do after the call to aws has completed.saveProduct
is called, another asynchronous function. saveProduct
must register a callback so that you can perform some action when the call to the database has been completed.res.send
api.post('somePost', function(req, resp) {
makeAWSCallAsync(params, function(err, awsRespProducts) {
saveProductsAsync(awsRespProducts, function(err, dbResp) {
// db call has been completed
resp.send();
});
});
});
This is very bare bones, and along the way errors should probably be checked. Once this is working, you could refactor to use promises, which would remove the nested callbacks.
Upvotes: 1