Tutorial 2 - Creating structured data

Your event app currently allows you to create new events, each of which only stores basic text details for your event’s name and description.

In this tutorial, you will extend the existing blueprint to capture more information about the event, such as the event’s date, time, and cost.

This tutorial takes around 30-40 minutes to complete.

Define extra properties for event documents

The following properties will be defined for event documents:

  • A string property called category, which stores one of three values - Live Music, Sporting Event, or Movie.

  • A number property called cost, which is used to store a number with decimals.

  • A string property called eventDate, which uses the date-time format to enforce RFC 3339 formatted date-time values.

  • A new boolean property called haveTicket, which can only store the values TRUE or FALSE.

To define these properties:

  1. In the event-app/api/schemas/ directory, open the event.json file.

  2. Copy the revised version of this file (below), over the existing content of this file.

    {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "properties": {
            "name": {
                "description": "The name of the event.",
                "type": "string",
                "example": "Music Festival"
            },
            "description": {
                "description": "The name of the event.",
                "type": "string",
                "example": "A festival of music, circus and magic."
            },
            "category": {
                "description": "The category of the event",
                "type": "string",
                "enum": ["Live Music", "Sporting Event", "Movie"],
                "example": "Live Music"
            },
            "cost": {
                "description": "The cost of the event.",
                "type": "number",
                "example": 100.00
            },
            "eventDate": {
                "description": "The date of the event.",
                "type": "string",
                "format": "date-time",
                "example": "2019-08-08T08:55:59Z"
            },
            "haveTicket": {
                "type": "boolean",
                "description": "If the user has a ticket to the event.",
                "example": true
            }
        },
        "required": ["name", "eventDate"]
    }

    The line "required": ["name", "eventDate"] indicates that the name and eventDate fields are mandatory.

    The existing content should already include the name and description entries of this file. Therefore, if you were to 'add' the new properties to your existing event.json file (i.e. without replacing the entire contents of your existing file with the code snippet above), you would only need to copy this code snippet from the comma immediately above category through to the end of this snippet, and paste this into your event.json file, from the closing brace for description over the remaining content of the file.

  3. Save the updated event.json file.

Copy the 'tutorial 2' files over to your event-app directory

Now copy the next level of your app’s functionality (which handles your API changes above) from the source tutorial repository over to your event-app directory.

  1. From the event-app directory, copy the content of the step3 directory to the event-app directory:

    $ cp -r ../tutorial/step3/*.* .
  2. Refresh or re-open the initial index.html file in the event-app directory.

Test the updated app

  1. Click the Create an event button to begin creating an event.
    Notice the additional fields on the Create an event dialog box: Category, Cost, Event date and Do you already have a ticket?.

  2. Specify some invalid data on this dialog box (e.g. add text in the Cost field) or omit mandatory data like the Name or Event date fields.

  3. Click Create event to try saving the event, and notice the error message showing which fields have invalid data at the top of the dialog box.

This error message you see comes directly from the Datastore service unchanged.

If you access your browser’s Network monitoring feature:

  • In Google Chrome, you can access this through More tools  Developer tools  Network,

  • In Firefox, through Web Developer  Network,

and run through the procedure above but click Create event directly (leaving all fields empty), you will see the JSON object in the response from the Datastore service:

{
  "title": "JSON does not validate",
  "status": 400,
  "invalid-params": [
    {
      "name": "name",
      "reason": "The property name is required"
    },
    {
      "name": "eventDate",
      "reason": "The property eventDate is required"
    }
  ]
}

Examine how the JS SDK handles errors

This content in the error message above is only accessible through your browser’s Network monitoring tools. However, to make this information appear in your app, and allow the user to know (in a friendlier manner) the cause of the issues (at the top of the Create an event dialog box), your app needs to handle this error response JSON object from the Datastore service.

The following code snippet shows the JS SDK syntax to handle failure when adding a new event (i.e. document) to the events collection.

/**
 * Adds a new event to My Event Manager
 */
const addEvent = () => {
    const data = getData('#createEvent');

    datastore.collection('events').add(data).then((event) => {
        printEvent(event);
        ...
    }).catch((error) => { (1)
        printError('#createEvent .modal-body', error); (2)
    });
};
1 The JavaScript function to handle the error response from the Datastore service in the event that the add() method does not return an HTTP status value of 201. The error response from the Datastore service is temporarily held by error.
2 Outputs the error data through the app.

Now that you understand the fundamentals of how to add additional properties to a document (accessible through an API endpoint) and handle an error returned from your Datastore service, you can now extend the functionality of your events app to handle the ability to edit your data.