BlogDADI Web's Built-in Data Helpers

DADI Web's Built-in Data Helpers

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.

Written By

Author
James Lambie

1 min read

Share This
DADI Web's Built-in Data Helpers

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.

Tutorials

Last Updated:

September 2019