Reputation: 340
I'm trying to create a module in nodejs so i create an Object called Client that has his constructor and some methods.
The problem is that the constructor run an async request (using request) and methods need things from construction to be invoked correctly.
How i can make the contructor synchronous?
function Client(id){
var token;
o = {
method: 'POST',
url: url + '/getToken',
headers: headers,
json: true,
body: id }
request(o).then(function(body) {
token = JSON.parse(body).token
})
function getValue(){
return new Promise(function(ff, rj) {
o = {
method: 'GET',
url: url + '?token=' + token,
headers: headers
}
request(o).then(function(body) {
ff(JSON.parse(body).value)
})
})
}
return{
getValue
}
}
I want to do something like this
var client = Client(id)
client.getValue().then(console.log)
but, because of async of request, when getValue return an error (token doesn't have a value yet) How i can do that? Thank you
Upvotes: 0
Views: 52
Reputation: 59231
You should take in token
as a dependency and do the async separately, perhaps in some kind of factory function.
function Client(token) {
this.getValue = function () {
return request({
method: 'GET',
url: url + '?token=' + token,
headers: headers
}).then(function (body) {
// Notice that you can return a synchronous value instead of a
// promise here. It will be wrapped in a promise and the next
// .then call will receive this returned value.
return JSON.parse(body).value;
});
}
}
function clientFactory (id) {
return request({
method: 'POST',
url: url + '/getToken',
headers: headers,
json: true,
body: id
}).then(function (body) {
var token = JSON.parse(body).token;
return new Client(token);
});
}
Or if you want to use es6 classes & arrow functions:
class Client {
constructor (token) {
this.token = token;
}
getValue () {
return request({
method: 'GET',
url: `${url}?token=${this.token}`,
headers: headers
}).then((body) => JSON.parse(body).value);
}
}
function clientFactory (id) {
return request({
method: 'POST',
url: `${url}/getToken`,
headers: headers,
json: true,
body: id
}).then((body) => new Client(JSON.parse(body).token));
}
The es6 class example is actually better because you're not recreating the getValue
method for every new instance of Client
. To make the first example as performant as the es6 example, you'd have to do it like this:
function Client(token) {
this.token = token;
}
Client.prototype.getValue = function () {
return request({
method: 'GET',
url: url + '?token=' + this.token,
headers: headers
}).then(function (body) {
return JSON.parse(body).value;
});
};
Now you should be able to do something like this:
var client = clientFactory(id).then(function (client) {
client.getValue().then(console.log);
});
Upvotes: 2