how to make http call api in a chain
my requirement is create account
i have to following events
1 check the account is exist or not 2 if account is not exists means i have create account
for account exists or not i wrote one function search (account name is unique )
Account.search({"name":"username"})
it retrieve the account name with "username" if it not found i am calling Account.save()
Account.da.js
exports.search = function (query) {
var deferred = Q.defer();
request({
url: config.ctxDa.url + "/account/search",
method: "GET",
qs: query,
useQuerystring: true,
headers: {"Content Type": "application/json"}
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
deferred.resolve(body);
}
else {
deferred.reject(error);
}
});
return deferred.promise;
};
// for creating account
exports.save = function (newAccount) {
var deferred = Q.defer();
request({
url: config.ctxDa.url + "/account",
method: "POST",
headers: {"Content Type": "application/json"},
json: newAccount
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
deferred.resolve(body);
}
else {
deferred.reject(error);
}
});
return deferred.promise;
};
this is my utility function to create account
exports.createAccount = function (account) {
var deferred = Q.defer();
Account.search({name: account.name}).then(function (body) {
if (JSON.parse(body).length == 0)
return;
return throw new Error("account already exists");
}).then(function () {
return Account.save(account).then(function (body) {
return deferred.resolve(body);
}, function (error) {
throw error;
})
}).catch(function (error) {
deferred.reject(error);
})
.done();
return deferred.promise;
}
what is best practice to call http calls in chain order
Your logic should work, although you do not need to create a new promise object in your createAccount function. Because both Account.search and Account.save are returning promises, you can just chain them and return the result:
exports.createAccount = function(account) {
return Account.search({name: account.name}).then(function(body) {
if (JSON.parse(body).length === 0) {
return;
}
// (you don’t need to `return`; `throw` by itself is enough)
throw new Error('account already exists');
}).then(function() {
return Account.save(account);
});
}
When you chain promises together using a chain of then() functions, the return value from the final step of the chain is what is returned to the caller. That’s why we return Account.search(…). It will ultimately return the final promise from that chain of then() functions. It will be a rejected promise if there was an error, or else the resolved promise from Account.save (which is what was returned by the final then() function).
We skipped the catch function, because you are simply passing any error up the chain. If there is an error, it will be passed back to the caller of createAccount and it’s their responsibility to handle it.
One more way to improve this code would be to handle the JSON.parse within the Account.search function. Instead of returning the body, it should return the parsed result, so you don’t have to do that in the createAccount function (or anywhere else that you may call Account.search). And I’m not sure what Account.save returns, but it looks like that could be parsed as well, before returning.