Over the last couple of years we’ve spent a lot of time debugging runtime issues with Events and the data they have access to.
After a short introduction to Web’s Event system, we cover two built-in helpers that are part of the data context for each page request in DADI Web.
🔗Events
The Event system in DADI Web provides developers with a way to perform tasks related to the current request, end the current request or extend the data context that is passed to the rendering engine.
An Event is a JavaScript file stored in your application’s workspace folder and attached to a page.json file using the "events"
array:
"events": [
"my-event"
]
It is declared in the following way, receiving the original HTTP request, the response, the data context and a callback function to return control back to the controller that called it:
const Event = function (req, res, data, callback) {
}
🔗The data context
The data
argument that an Event receives is JSON which is eventually passed to the template rendering engine once all the Datasources and Events have finished running. data
may contain some or all of the following:
- metadata about the current page
- request parameters
- data loaded by all datasources that have been run before the Events started executing
- data added by previous Events
- global configuration settings
{
"query": {},
"params": {
"category": "beauty",
"subCategory": "makeup"
},
"pathname": "/beauty-hair/makeup/article-one",
"host": "127.0.0.1:8000",
"debug": true,
"page": {
"name": "article",
"description": "Article page",
"language": "en"
},
"global": {
"baseUrl": "http://localhost:8000",
"environment": "development"
}
"article": {
"results": [
{
"slug": "article-one",
"title": "Article One",
"category": "beauty"
}
],
"metadata": {
"limit": 1,
"page": 1,
"totalCount": 19,
"totalPages": 19,
"nextPage": 2
}
}
}
🔗Data from datasources
All datasources that retrieve data from a DADI API return data in the following format:
{
"results": [
{
"slug": "article-one",
"title": "Article One",
"category": "beauty"
}
],
"metadata": {
"limit": 1,
"page": 1,
"totalCount": 19,
"totalPages": 19,
"nextPage": 2
}
}
The results are added to the data context using the datasource’s key
property. Running a datasource configured with "key": "article"
would result in the following in the data context:
"article": {
"results": [
{
...
}
],
"metadata": {
...
}
}
🔗Common Event errors
While helping people to implement applications using DADI Web, we’ve encountered many issues when trying to access data within an Event that simply doesn’t exist in the data context.
🔗No data loaded
For example, making an assumption that the datasource “people” has returned results and the data context has been populated:
let myPerson = data.people.results[0]
If the context doesn’t contain the "people"
property, perhaps because the datasource wasn’t attached to the page, then the Event fails with:
TypeError: Cannot read property 'results' of undefined
🔗No "results"
property
Another way to cause an Event to fail is to reference an nonexistent "results"
property. Perhaps the data we’re expecting came from an API other than a DADI API (such as Twitter or Instagram) and the required data has a different structure.
let mostRecentInstagramPhoto = data.instagram.results[0]
If there isn’t a "results"
array at data.instagram
, the Event will fail with:
TypeError: Cannot read property '0' of undefined
🔗Introducing built-in helper functions
With these two common errors in mind, we decided it was time to introduce some helper functions into the mix: has()
and hasResults()
.
These helpers are added to the data context before it is passed to the Event system:
{
has: [Function],
hasResults: [Function],
"query": {},
"params": {
"category": "beauty",
"subCategory": "makeup"
},
...
}
🔗has()
The has()
function can be used to check that a property exists in the data context:
const Event = function (req, res, data, callback) {
if (data.has('instagram')) {
// do something with data.instagram
} else {
// no instagram property
res.statusCode = 404
res.end('Not found')
}
callback()
}
🔗hasResults()
The hasResults()
function can be used to check that the results of a DADI API datasource exist, and that there is at least one value in the "results"
array:
const Event = function (req, res, data, callback) {
if (data.hasResults('people')) {
// do something with people
let mostRecentPerson = data.people.results[0]
} else {
// no people results
res.statusCode = 404
res.end('Not found')
}
callback()
}
🔗Conclusion
The two helper functions added to the data context in DADI Web help to make your application more robust and keep the code cleaner. Don’t worry, we got tired of writing the same statements over and over as well:
if (data.people &&
data.people.results &&
data.people.results[0]) {
// finally do something
}
We hope you find these as useful as we have, and welcome any suggestions for additional helpers that might save you time and energy!
For more information about Events in DADI Web, see the documentation.