This repository has been archived by the owner on May 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Common Usage
yusufsipahi edited this page Jul 19, 2020
·
15 revisions
- Ask-Sdk-Jsx-For-Apl enables developers to use React components to model their responses. It does so by using JSX and React’s render lifecycle to attach
Alexa.Presentation.APL.RenderDocument
directive to the responseBuilder object.
- Following code shows how a Ask-Sdk-Jsx-For-Apl APL document can naturally fit into the LaunchIntent handler.
// MainSkill.js
import * as Alexa from 'ask-sdk';
import { LaunchIntentHandler } from './handlers/LaunchIntentHandler';
const builder = Alexa.SkillBuilders.custom();
const handler = builder.addRequestHandlers(
new LaunchIntentHandler()
).lambda();
module.exports = { handler };
// handlers/LaunchIntentHandler.jsx
import * as Alexa from 'ask-sdk';
import * as React from "react";
import { LaunchApl } from './apl/LaunchApl';
import { AplDocument } from 'ask-sdk-jsx-for-apl';
class LaunchIntentHandler {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
}
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
//React Component render cycle is triggered via getDirective method of AplDocument
return responseBuilder
.addDirective(new AplDocument(<LaunchApl />).getDirective())
.speak("Welcome to my first Vesper skill")
.getResponse();
}
};
module.exports = { LaunchIntentHandler };
// apl/LaunchApl.jsx
import * as React from 'react';
import { APL, MainTemplate, Frame, Container, Text } from 'ask-sdk-jsx-for-apl';
//React Component of LaunchIntent APL
export class LaunchApl extends React.Component {
constructor(props) {
super(props);
this.launchMessage = 'Welcome to my first ask-sdk-jsx-for-apl skill!';
}
render() {
return (
<APL theme="dark">
<MainTemplate>
<Frame
width="100vw"
height="100vh"
backgroundColor="rgb(22,147,165)"
>
<Container
alignItems="center"
justifyContent="spaceAround"
>
<Text
text={this.launchMessage}
fontSize="50px"
color="rgb(251,184,41)"
/>
</Container>
</Frame>
</MainTemplate>
</APL>
);
}
}
- The following output shows the directive generated by using the above react component.
// Alexa.Presentation.APL.RenderDocument JSON Response
{
"type": "Alexa.Presentation.APL.RenderDocument",
"document": {
"type": "APL",
"version": "1.3",
"import": [],
"theme": "dark",
"mainTemplate": {
"parameters": [],
"items": [
{
"items": [
{
"items": [
{
"items": [],
"text": "Welcome to my first ask-sdk-jsx-for-apl skill!",
"fontSize": "50px",
"color": "rgb(251,184,41)",
"type": "Text"
}
],
"alignItems": "center",
"justifyContent": "spaceAround",
"type": "Container"
}
],
"width": "100vw",
"height": "100vh",
"backgroundColor": "rgb(22,147,165)",
"type": "Frame"
}
]
}
}
}
- The following example shows a usage of dynamic APL Response to check for the viewport shape on runtime and service different width and height values for the APL documents.
// LaunchIntentHandler.jsx
import * as React from 'react';
import * as Alexa from 'ask-sdk-core';
import { LaunchApl } from './apl/LaunchApl';
class LaunchIntentHandler {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
}
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
const viewportShape = handlerInput.requestEnvelope.context.Viewport.shape;
const aplParameters = {
width: '100vw',
height: '100vh'
};
if (viewportShape === 'ROUND') {
aplParameters.width = '80vh';
aplParameters.height = '80vh';
}
//Provide parameters to LaunchApl component.
const LaunchAplDocument = new AplDocument(
<LaunchApl aplParameters={aplParameters}/>
).getDirective();
return responseBuilder
.addDirective(LaunchAplDocument)
.speak("Welcome to my first ask-sdk-jsx-for-apl skill")
.getResponse();
}
};
// apl/LaunchApl.jsx
import * as React from 'react';
import { APL, MainTemplate, Frame, Container, Text } from 'ask-sdk-jsx-for-apl';
export class LaunchApl extends React.Component {
constructor(props) {
super(props);
this.launchMessage = 'Welcome to my first ask-sdk-jsx-for-apl skill!';
}
render() {
//width and height parameters are provided from calling elements.
return (
<APL theme="dark">
<MainTemplate>
<Frame
width={this.props.aplParameters.width}
height={this.props.aplParameters.height}
backgroundColor="rgb(22,147,165)"
>
<Container
alignItems="center"
justifyContent="spaceAround"
>
<Text
text={this.launchMessage}
fontSize="50px"
color="rgb(251,184,41)"
/>
</Container>
</Frame>
</MainTemplate>
</APL>
);
}
}
-
The best way to make an APL component more maintainable and controllable is to break it into multiple components.
-
The following example shows the reuse of Container component to serve different content.
// apl/WorkoutApl.jsx
import * as React from 'react';
import { APL, Container, Image, Text } from 'ask-sdk-jsx-for-apl';
import WorkoutColumn from './workout-column-apl';
class WorkoutApl extends React.Component {
private renderWorkoutPartsImage() { ... }
private renderWorkoutStepsImages() { ... }
private renderWorkoutStepsTexts() { ... }
render() {
return (
<APL theme="dark">
<MainTemplate>
<Container width="100%" height="80vh" direction="row">
<WorkoutColumn>
{
this.renderWorkoutPartsImage();
}
</WorkoutColumn>
<WorkoutColumn>
{
this.renderWorkoutStepsImages();
}
</WorkoutColumn>
<WorkoutColumn>
{
this.renderWorkoutStepsTexts();
}
</WorkoutColumn>
</Container>
</MainTemplate>
</APL>
);
}
}
export default WorkoutApl;
// apl/WorkoutColumn.jsx
import * as React from 'react';
import { Container } from 'ask-sdk-jsx-for-apl';
class WorkoutColumn extends React.Component {
render() {
return (
<Container width="30%" height="100%"
paddingBottom="16dp"
paddingLeft="16dp"
paddingRight="16dp"
paddingTop="16dp"
spacing="16dp">
{this.props.children}
</Container>
);
}
}
export default WorkoutColumn;