When we started our express application and accessed it in the browser, an error raised on the console and no response was sent back to the browser. The reason for this behaviour is that the database connection is not correctly configured, and the request from our application fails.
For a better understanding I have refactored the code to „old-school“ Javascript. The functions are called in a promise chain.
router.get('/', function(req, res, next) {
useServer(serverConfig)
.then(
function(server){
return server.useDatabase(databaseConfig)
})
.then(
function(database){
return database.bulkCreateDocuments(createOptions)
})
.then(
function(response){
const unids = response.documents.map(doc => doc['@unid']);
res.render('index', { title: 'Express', result: `Documents created: ${unids}` });
}
);
});
1. The get method of the router calls the anonymous function (2nd parameter).
2. The chain starts: This function calls the useServer method of the domino-db package with the serverConfig.
3. If everything is OK, the next method in the chain is called with the server object (the result of the previous operation).
4. If everything is OK, the next method in the chain is called with the database object.
5. If everything is OK, the next method in the chain is called with the result object.
Promises have two callback functions: The first parameter is always the „success“ callback, and the second the „error“ callback. But we are not using a second parameter, because this allows us to use a catch function at the end of our chain:
router.get('/', function(req, res, next) {
useServer(serverConfig)
.then(
... )
.then(
... )
.then(
... )
.catch(
function(error) {
console.log(error);
res.render('error', { title: 'Error', error });
}
);
});
The catch block handles every error in our chain, and renders the view ‚error‚ with the reason of the failure.
If we now restart our application, the error is displayed to the end user with a stacktrace:
And now, we are refactoring the code using the arrow syntax:
router.get('/', (req, res) => {
useServer(serverConfig)
.then(server => server.useDatabase(databaseConfig))
.then(database => database.bulkCreateDocuments(createOptions))
.then(response => {
const unids = response.documents.map(doc => doc['@unid']);
res.render('index', { title: 'Express', result: `Documents created: ${unids}` });
})
.catch(error => {
console.log(error);
res.render('error', { title: 'Error', error });
}
);
});
A lot shorter, isn’t it?
At the end, we are using async/await syntax to shorten the promise chain too:
router.get('/', (req, res) => {
useServer(serverConfig).then(
async server => {
const database = await server.useDatabase(databaseConfig);
const response = await database.bulkCreateDocuments(createOptions);
const unids = response.documents.map(doc => doc['@unid']);
res.render('index', { title: 'Express', result: `Documents created: ${unids}` });
}
).catch(error => {
console.log(error);
res.render('error', { title: 'Error', error });
});
});