Injecting Model Data

Often it is useful to pass data from the fulfillment to a template to be rendered. This keeps the display from being static and helps provide useful visual information to the user. A skill that deals with weather forecasts, for example, could display a five-day forecast while Alexa speaks the current weather conditions. It would be less useful if the display only showed a fixed logo or text while Alexa speaks the weather.

You can pass data to an APL template using the datasources property of the Alexa.Presentation.APL.RenderDocument directive. For the “enjoy your trip” screen, we could pass along the trip details as well as some text from the intent handler to the APL template like this:

 const​ locale = Alexa.getLocale(handlerInput.requestEnvelope);
  handlerInput.responseBuilder
  .addDirective({
  type : ​'Alexa.Presentation.APL.RenderDocument'​,
  document: require(​'./apl/tripComplete.json'​),
» datasources: {
»"tripData"​: {
»"titleText"​: handlerInput.t(​'ENJOY_YOUR_TRIP_TITLE'​),
»"destination"​: destination,
»"departureLabel"​: handlerInput.t(​'DEPARTURE_LABEL'​),
»"departureDate"​: toFriendlyDate(departureDate, locale),
»"returnLabel"​: handlerInput.t(​'RETURNING_LABEL'​),
»"returnDate"​: toFriendlyDate(returnDate, locale)
» }
» }
  });

For convenience, all of the properties are carried in a single object named tripData. The title text and date labels are pulled from the languageStrings.js module using handlerInput.t(), the same as the text that Alexa speaks in responses. This ensures that both the spoken text and the visual displays are presented in the user’s chosen language.

The trip’s destination and dates are also passed through the model data. Because the dates are going to be displayed, they are passed through a toFriendlyDate() function that is defined in a separate utility module:

 const​ toFriendlyDate = ​function​(dateString, locale) {
 var​ dateDate = ​new​ Date(dateString);
 return​ dateDate.toLocaleDateString(locale,
  {month:​"long"​, day:​"numeric"​, year: ​"numeric"​});
 };
 
 module.exports = toFriendlyDate;

The toFriendlyDate() function takes the given date string and formats it in a locale-specific friendly date format. For example, if the locale is “en-US” and the date is 2021-10-25, then the friendly date will be “October 25, 2021”. On the other hand, for the “es-US” locale, the friendly date will be “25 de octubre de 2021”.

With the data being passed to the APL template, we can start changing some of the Text components to present the model data instead of hardcoded text. For instance, we can change the text property of the title Text component to render values from the model like this:

 {
 "type"​: ​"Text"​,
 "width"​: ​"100vw"​,
 "height"​: ​"60dp"​,
 "color"​: ​"yellow"​,
 "fontSize"​: ​"42dp"​,
»"text"​: ​"${payload.tripData.titleText} ${payload.tripData.destination}"
 },

The value of the text property uses ${} notation to reference the titleText and destination properties from the tripData object that is carried in payload.

In order for this to work, however, we’ll need to declare the payload parameter in the template. Near the top of the mainTemplate, add a parameters property that declares payload like this:

 "mainTemplate"​: {
 "parameters"​: [
 "payload"
  ],
  ...
 }

As for the date Text components, their text properties reference model data in a very similar way:

 {
 "type"​: ​"Text"​,
 "color"​: ​"lightblue"​,
 "fontSize"​: ​"24dp"​,
 "paddingTop"​: ​"12dp"​,
»"text"​: ​"<b>${payload.tripData.departureLabel}:</b>
» ${payload.tripData.departureDate}"
 },
 {
 "type"​: ​"Text"​,
 "fontSize"​: ​"24dp"​,
 "color"​: ​"lightblue"​,
 "paddingTop"​: ​"12dp"​,
»"text"​: ​"<b>${payload.tripData.returnLabel}:</b>
» ${payload.tripData.returnDate}"
 }

There’s one more thing we can use the model data for in this template. Rather than hard-code a URL for the planet image to always display Jupiter, we can ${payload.tripData.destination} to dynamically create that URL in the Image component like this:

 {
 "type"​: ​"Image"​,
 "width"​: ​"300dp"​,
 "height"​: ​"250dp"​,
»"source"​: ​"https://starport75.dev/images/planets/
» ${payload.tripData.destination}.png"
 }

Now the template is fully dynamic with every part, except the background images, populated from model data. Redeploy the skill and give it a try. The resulting display should look like this:

images/apl/EnjoyYourTripToUranus.png

Here, a trip was planned to Uranus between February 19th and 21st. What’s more, the planet image is an image for the chosen planet.

So far, we’ve treated APL as a one-way form of communication where an APL template is sent from the server and rendered on the device’s screen. Let’s see how to turn things around by handling touch events.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset