Javascript APIs with async properties

omrilotan
2 min readFeb 11, 2018

Getter properties are a great way to mask logic and expose what appears as static values. I find it extremely elegant to differentiate functionality from attributes. This logic may hide lazy calculations to be performed only on-demand, or it may hide logic that’s based on object’s, or even application state.

For example, a User object may have functionality like user.goOnline(), it should have attributes like user.isOnline. The check if a user is online should be performed on demand because this status may change from moment of instantiation to the moment of querying.

With the emerging of async/await in Javascript, it is now possible to create such lazy getters by pointing them to promises, creating more semantic APIs.

class User {
constructor(id) { ... }
goOnline() { ... }
addBadge(type) { ... }
get isOnline() {
return
fetch(`/${this.username}/online`)
.then(response => response.json())
.then(data => data.isOnline)
.catch(error => { throw error; });
}

}
const myUser = new User('acb33259');// Functionality
myUser.goOnline();
// Attribute
if (await myUser.isOnline) {
// Functionality
myUser.addBadge('online');
}

Static object can also leverage this way of typing. An API object pointing to async properties may also appear more readable.

const api = {
get request() {
return new Promise(resolve => setTimeout(() => resolve({status: 200}), 1000))
}
};
(async () => {
const { status } = await api.request;
console.log(status); // 200
})();

When importing between modules — I feel the appeal is even greater.

module.exports = async () => {
const { request } = require('./api');
const { data } = await request;
// Do amazing things with the data
};

And this just opens up endless sugary syntactic possibilities.

The following is a (simplified) real life example where I found using async getters made the final logic cleaner.
`git tag -a ${tag} -m "${await message}"`

--

--