Accessing Payload Data
There are a few different methods for accessing and manipulating data from workflow payloads and device data queries. Depending on the use case, you may run across a point while building your app where you’re asked to supply a data reference in one of the following formats.
{
"data" : {
"aNumberProp": 42,
"aStringProp": "Hello world",
"aBooleanProp": true,
"aFalsyProp" : 0,
"aDecimal": 123.456789,
"anUndefinedProp": undefined,
"aNullProp": null,
"aJavascriptDateObject": Wed Sep 28 2016 15:40:25 GMT-0400 (EDT),
"anArray": [
44,
"Goodbye world",
false,
{
"anObjectPropInAnArray": "I'm deep!"
}
],
"anObject": {
"aNestedArray": [
"I'm a string!",
20,
{ }
],
"aNestedNumber": 56,
"aNestedString": "Wally World"
},
"anHtmlString": "<span>Wall-E</span>"
}
}
Payload Paths
Many workflow nodes, such as the HTTP Node, the Get and Store Value nodes and the Math Node, require users to define a payload path at which either data will be accessed for evaluation, or at which the returned result of an operation will be stored. In these cases we use payload paths.
Payload paths are dot-separated references to object properties, such as foo.bar
. If any property in the chain returns undefined
, the value of the payload path will also return undefined.
Square brackets wrapped around a property name can be used in a handful of cases:
- Accessing an array value by index. e.g.
data.anArray.[0]
returns the first value in the array at that path. - Accessing a specific character of a string by index. e.g.
data.aString.[1]
returns the second letter of the string at that path. - Escaping payload properties that have spaces or other special characters. e.g.
data.[a silly property name]
.
Examples
Given our example object, here is how we would reference many of the properties using payload paths:
data.aNumberProp // 42
data.aBooleanProp // false
data.aNullProp // null
data.aJavascriptDateObject // Wed Sep 28 2016 15:40:25 GMT-0400 (EDT)
. // (returns the entire example object)
data.anArray.[1] // "Goodbye world"
data.anArray.1 // (invalid syntax)
data.anArray.[1].[2] // o (The character at index 2 of the array item at index 1)
data.anArray.[3] // { "anObjectPropInAnArray": "I'm deep!" }
data.anArray.[3].anObjectPropInAnArray // "I'm deep!"
data.anArray.[8] // (undefined. This index does not exist on the array.)
data.anObject.aNestedNumber // 56
data.anObject.aNestedArray // ["World Star!", 20, { }]
data.anObject.aNestedArray.[1] // 20
data.aNonexistentObject.aMissingProp // (undefined. "aNonExistentObject" is not a property of "data")
aNumberProp // (undefined. This is not a top-level property of our object.)
Payload paths do not accept variables within the path definition; the paths must be static references.
String Templates
String templates are Handlebars templates – that is, they are constructed using a payload path that is wrapped in double curly brackets, such as {{foo.bar}}
. The value at the specified path should resolve to a printable property; specifically, the value should be of the type “string”, “number”, “boolean” or “undefined”. Objects referenced in this way will return [object Object]
, and arrays will return as comma-concatenated strings of all array values, such as foo,bar,42,false
.
Areas within the app that call for a string template do not necessarily have to include a variable; it is perfectly acceptable to put a static string value in place of a template.
String templates appear in a number of places within the Losant Platform; in all cases, they serve one of two purposes:
- Referencing payload values, such as for setting state in the Device State Node.
- Formatting values for output, such as in the GPS History block’s tooltip or the SMS Node’s message.
Embedded Workflows
Note: The HTML-escaping, block helpers, and format helpers described below are not valid within Embedded Workflows. In node configuration properties that accept a string template, Embedded Workflows will only accept a direct reference to the value.
Escaping HTML
By default, HTML within a Handlebars helper is escaped to prevent malformed HTML from breaking the page layout. If you wish to override this feature, put your string templates inside of triple curly brackets, e.g. {{{aValueWithHtmlTags}}}
. You may, for example, wish to include HTML tags in the message body of the Email Node.
Conditional Block Helpers
Conditional block helpers allow for rendering content if a given condition returns true; they also support rendering content in case the condition is not met, using the {{else}}
syntax. For example:
Hello, ! User is not signed in.
Values in block helpers can themselves be wrapped in subexpressions, such as:
Hello, Admin! Hello, User!
The following block helpers are available. If you have an idea for a new helper, please let us know about it in our forums.
{{#if val}}
Conditionally renders its inner content if val
is not false
, undefined
, null
, ""
(empty string), 0
, or []
(empty array). This is a built-in Handlebars helper and is not specific to Losant.
{{#unless val}}
The inverse of {{#if}}
; it renders its inner content if val
is false
, undefined
, null
, ""
(empty string), 0
, or []
(empty array). This is a built-in Handlebars helper and is not specific to Losant.
{{#eq p1 p2}}
Renders its inner content if p1
and p2
are equal by shallow comparison.
{{#ne p1 p2}}
Renders its inner content if p1
and p2
are not equal.
{{#gt p1 p2}}
Renders its inner content if p1
is greater than p2
.
{{#gte p1 p2}}
Renders its inner content if p1
is greater than or equal to p2
.
{{#lt p1 p2}}
Renders its inner content if p1
is less than p2
.
{{#lte p1 p2}}
Renders its inner content if p1
is less than or equal to p2
.
{{#match str regExpStr}}
Renders its inner content if str
matches the regular expression regExpStr
.
{{#includes collection value}}
Renders its inner content based on the following:
- If
collection
is a array andvalue
is equal (by deep comparison) to an entry in that array. - If
collection
is an object andvalue
is equal (by deep comparison) to one of the top-level property values. - If
collection
is a string andvalue
(when cast to a string) is equal to or matches part of that string.
Iterating Over Values
One very useful feature of string templates is the ability to iterate over arrays, objects, strings, and numbers using the {{#each}}
block helper (another native Handlebars helper). When doing so, a few variables become available to the user in the context of the loop:
{{@first}}
will be true if this is the first iteration of the loop, and will be false otherwise.{{@index}}
returns a number corresponding to the index of the current item in the loop. One possible use of this value is to know how many times the loop has executed, and to stop executing additional code within the loop based on this value.{{@key}}
returns the name of the current key when iterating over an object, otherwise it will be the same as{{@index}}
. You can use this to execute a different string template based on the current item in the loop.{{@last}}
will be true if this is the last iteration of the loop, and will be false otherwise.{{this}}
represents the current item in the loop; or, put another way, the value at{{anArray.[@index]}}
or{{anObject.[@key]}}
.
When iterating over a string, the string is treated as an array of the individual characters of the string. When iterating over a number, the number is treated as an array of the integers starting at 0 all the way up to (but not including) the given number.
The {{else}}
statement, when used within an {{#each}}
block, will render its contents if the value provided to the {{#each}}
helper is empty. This allows for easily creating list empty states in Experience Views.
Note: When inside an {{#each}}
block helper, the render context changes to the current iterated value. If you need to access a property that is outside of this context, you may do so one of two ways:
- Use
../
in front of your variable name to step up one level in the context object - Use
@root
as the first segment in the variable to start at the root of the context object
For example, given a payload of:
{
"city": "Cincinnati",
"state": "Ohio",
"streets": ["Broadway", "Sycamore", "Main"]
}
And a string template of:
<ul>
<li> , , </li>
</ul>
The output would be the following:
<ul>
<li>Broadway, Cincinnati, Ohio</li>
<li>Sycamore, Cincinnati, Ohio</li>
<li>Main, Cincinnati, Ohio</li>
</ul>
Changing Evaluation Context
By wrapping your content in the native Handlebars {{#with}}
block helper, you can change the evaluation context of any helper within the block. This can make it easier to reference deeply nested properties and avoid collisions with other variable names.
The {{else}}
statement, when used within a {{#with}}
block, will render its contents if the value provided to the {{#with}}
helper is empty.
Format Helpers
Handlebars helpers can also mutate a given value in place and print the result. Losant provides the following formatting helpers:
{{add val1 val2}}
Casts the two values as numbers and adds them.
{{array value1 value2 value3}}
Creates an array out of all of the given arguments. Attempting to print this value directly will output the items joined by a comma; this helper is used almost exclusively to construct arguments for other helpers inline. For example:
{{ceil val}}
Casts the value as a number and returns the ceiling of that number. See Math.ceil().
{{colorMarker color}}
Renders a dashboard pin using the provided color
argument. This helper is most useful when conditionally rendering points in a GPS History Block.
{{currentDateTime formatStr tz="UTC" locale="en"}}
Returns the current date/time formatted by the provided format string. The format string follows Moment.js format syntax, and the default is ‘L LTS’.
The tz
and locale
arguments are optional. See {{formatDate}}
for more information.
{{divide val1 val2}}
Casts the two values as numbers and divides them.
{{dashboardUrl id queryParamKey1='queryParamValue1' ...}}
Creates a link to the dashboard at the given ID (defaults to the current dashboard) and adds the optional query parameters. To pass a nested object of parameters, such as for dashboard context, include the parameter as ctx=(obj key1=valueFromField key2="staticValue")
.
{{decodeBase64 val}}
Treats val
as Base64-encoded and returns a decoded string (UTF-8 character set).
{{decodeURI str}}
Returns str
as a decoded URI.
{{decodeURIComponent str}}
Returns str
as a decoded URI component.
{{defaultTo val default}}
Returns the value of default
if the value of val
is null
, undefined
, or an empty string. Otherwise returns the value of val
.
{{encodeBase64 val}}
Treats val
as a string, and returns the Base64-encoded version of that string (UTF-8 character set).
{{encodeURI str}}
Returns str
as an encoded URI.
{{encodeURIComponent str}}
Returns str
as an encoded URI component.
{{evalExpression str ctx}}
Evaluates str
as an expression, using ctx
as the context for variable lookups. If ctx
is not provided, the overall payload is used. Cannot be used recursively, or combined with template
.
{{floor val}}
Casts the value as a number and returns the floor of that number. See Math.floor().
{{format val formatStr tz="UTC" locale="en"}}
- If
val
is a number, returns the number in the D3 format matching theformatStr
parameter (default “,.6”). - If
val
is a JavaScript Date object, returns the date in the Moment.js format matching theformatStr
parameter (default “L LTS”). - If
val
is an object, returns the stringified object and ignores other parameters. (See{{jsonEncode}}
for better rendering of stringified objects.) - For all other formats,
val
is returned as a string without mutation.
The tz
argument is optional and only applies if val
is a Date object. See {{formatDate}}
for more information.
The locale
argument is optional. It accepts a locale code and defaults to the user’s current browser’s locale in - or, in server settings (such as in workflow executions), it defaults to “en” (English).
- When rendering a number with a
locale
argument, this renders the number as is done in the provided locale (separators and decimals). - See
{{formatDate}}
) for the behavior when rendering a date.
When locale
is not provided, it defaults to the browser’s locale in client-side usages (such as when rendering values in a dashboard description or the workflow template tester). In server settings (such as in workflow executions and experience page rendering), it defaults to “en” (English).
{{formatDate val formatStr tz="UTC" locale="en"}}
Casts the given value as a date, and then formats it using the formatStr
parameter (defaults to “L LTS”).
The tz
argument is optional; it accepts a timezone name for rendering the date against the timezone’s offset from UTC.
The locale
argument is optional; it accepts a locale code to use for rendering the date in the given locale’s standard format (though certain formatStr
arguments may override this argument’s effect).
When this helper is used in a browser setting (such as when rendering values in a dashboard description or the workflow template tester), tz
defaults to the user’s current timezone and locale
defaults to the browser’s locale setting. In server settings (such as in workflow executions and experience page rendering), tz
defaults to “UTC” and locale
defaults to “en” (English).
{{formatDateRelative date relativeTo locale="en"}}
Outputs a relative date value (such as “5 minutes ago”). Date is calculated relative to the relativeTo
parameter, which defaults to the current time when not set.
The locale
argument is optional. See {{formatDate}}
for more information.
{{formatGps gpsStr formatStr precision}}
Takes the given GPS coordinate, in any of the supported formats, and reformats to the desired format. formatStr
can be decimal
(the default), degrees
, sexagesimal
, or gga
. precision
will round the coordinates to the given number of decimal places (default 6).
{{gpsDistance gpsStr1 gpsStr2}}
Takes two GPS points and returns the distance between them (in meters).
{{gpsIsPointInside point polyArray}}
Takes a GPS point and an array of points making up a polygon geofence, and renders “true” if point
is within the bounds of polyArray
and “false” if not.
For example, given the following context …
{
"point": "40,60",
"polyArray": [
"0,0",
"45,45",
"45,90",
"0,45",
"0,0"
]
}
… and the following use of the {{gpsIsPointInside}}
helper …
… the output would be:
true
{{indexByKey objArray keyValue keyPath}}
Returns the index of the first object in the objArray
whose value at keyPath
deeply matches keyValue
. The argument keyPath
is optional, defaulting to the path key
. If there is no match found, -1
is returned.
For example, given the following context …
{
"objArray": [
{ "age": 86, "name": { "first": "Alan", "last": "Alda" } },
{ "age": 98, "name": { "first": "Bob", "last": "Barker" } },
{ "age": 46, "name": { "first": "Candace", "last": "Cameron" } }
]
}
… and the following use of the {{indexByKey}}
helper …
… the output would be:
1
{{join array separator}}
Joins the values in the given array as a single string, separated by the given separator. If no separator is given, defaults to ,
.
{{jsonDecode val}}
Treats val
as a JSON string and parses it. If not parsable, will return undefined
. This helper is used almost exclusively to construct arguments for other helpers inline.
{{jsonEncode val spacerStr}}
Returns val
stringified. If no spacer string is given (for adding whitespace for readability to the output), defaults to adding no whitespace.
{{last val}}
Returns the last item in an array or the last character in a string. If there are no items in the given array or string, or if the input value is not one of those types, the helper returns undefined
and renders an empty string.
{{length val}}
Returns the following string based on the type of val
:
- If
val
is an array, returns the number of items in the array. See Array.length. - If
val
is an object, returns the number of keys on the object. See Object.keys(). - If
val
is a string, returns the length of the string. See String.length. - For everything else, returns
undefined
.
{{lookup collection property}}
Allows for dynamic parameter resolution using Handlebars variables. This is a built-in Handlebars helper and is not specific to Losant.
{{lower str}}
Returns str
converted to all lowercase characters.
{{max val1 val2}}
Returns the larger of the two arguments. See Math.max().
{{merge val1 val2 val3}}
Shallow merges all the given arguments into a single object. If keys are duplicated, the value from the last argument with that key is used. Attempting to print this value directly will output [object Object]
; this helper is used almost exclusively to construct arguments for other helpers inline.
{{min val1 val2}}
Returns the smaller of the two arguments. See Math.min().
{{multiply val1 val2}}
Casts the two values as numbers and multiplies them.
{{obj key1=val1 key2=val2 ...}}
Constructs a hash of the provided key-value pairs. Attempting to print this value directly will output [object Object]
; this helper is used almost exclusively to construct arguments for other helpers inline. For example:
{{queryStringEncode object}}
Takes the given object and converts it to a URL query string. Note: In almost all cases, this helper should be HTML-escaped by wrapping the helper in three curly braces, like so:
{{scaleLinear fromLow fromHigh toLow toHigh value}}
Scales the given value
from the domain defined by fromLow
and fromHigh
to the range defined by toLow
and toHigh
. Similar to the Arduino Map function.
For example, given the following use of the {{scaleLinear}}
helper …
… the output would be:
1000
{{substring sourceStr startIdx optionalEndIdx}}
Returns sourceStr
from the start index up to and excluding the end index, or to the end of the sourceStr
if no end index is supplied.
See String.prototype.substring().
{{subtract val1 val2}}
Casts the two values as numbers and subtracts them.
{{template str ctx}}
Evaluates str
as string template, using ctx
as the context for variable lookups. If ctx
is not provided, the overall payload is used. Cannot be used recursively, or combined with evalExpression
.
{{toHtml object}}
Takes the given object and converts it to an HTML/XML document string. The object must be of the same format that the HTML Parser Node outputs in JSON mode.
{{trim str}}
Returns str
with all whitespace trimmed from the start and end.
{{titleCase str}}
Returns str
with title capitalization rules applied.
{{typeof val}}
Returns the following string based on the type of val
:
- If
val
is a number, returnsnumber
. - If
val
is a boolean, returnsboolean
. - If
val
is a string, returnsstring
. - If
val
is null, returnsnull
. - If
val
is undefined, returnsundefined
. - If
val
is an array, returnsarray
. - If
val
is a date object, returnsdate
. - If
val
is an object, returnsobject
.
{{upper str}}
Returns str
converted to all uppercase characters.
{{valueByKey objArray keyValue keyPath valuePath}}
Returns the value at valuePath
on the first object in the objArray
whose value at keyPath
deeply matches keyValue
. The arguments keyPath
and valuePath
are optional, defaulting to the paths key
and value
. If there is no match found, a blank result is returned.
For example, given the following context …
{
"objArray": [
{ "age": 86, "name": { "first": "Alan", "last": "Alda" } },
{ "age": 98, "name": { "first": "Bob", "last": "Barker" } },
{ "age": 46, "name": { "first": "Candace", "last": "Cameron" } }
]
}
… and the following use of the {{valueByKey}}
helper …
… the output would be:
Barker
String Template Examples
Using our example object from above, let’s see what each of these string templates would print …
<span>My New Post</span>
=> <span>Wall-E</span>
=> 44,Goodbye world,false,[object Object]
(all items in the array concatenated by commas)
=> G
(the character at index 0 of the item at index 1 of the array)
=> (invalid syntax)
(0 is not a property of the array; should be [0] to access by index)
=> (prints nothing)
(index does not exist on the array.)
The number is
=> The number is 42
The number is
=> (prints nothing. The condition fails.)
Truth! Fiction!
=> Fiction! (0 is falsy so the condition falls to the else statement.)
: ;
=> 0: 44; 1: Goodbye world; 2: false; 3: [object Object];
: ;
=> aNestedArray: World Star!,20,[object Object]; aNestedNumber: 56; aNestedString: Wally World;
: -- No object!
=> No object!
First number is greater
=> First number is greater
Second number is greater
=> (prints nothing)
Equal! Not equal
=> Not equal (cases don't match)
Equal! Not equal
=> Equal! (cases match after running through the "lower" subexpression)
=> (the stringified object)
=> 1,234.6
=> Hello%20world
Ba de ya! Play something else
=> Ba de ya!
=> 42
=> Hello world
=> true
=> (prints nothing)
=> (prints nothing)
=> Goodbye world
=> [object Object]
=>
Expressions
Sometimes it is necessary to evaluate our data and determine which of two (or many) paths to follow as a result of the evaluation, such as in the dashboard Indicator block’s expressions and the workflow Conditional Node. In these cases we use expressions.
An expression is a combination of string templates and JavaScript operators that forms a “JavaScript-like” expression after parsing through the Handlebars engine. The expression returns a value; depending on the use case, that value may be evaluated as truthy or falsy to determine which branch a workflow follows (as in the Conditional Node), or the value may be added to a payload (as in the Math Node).
Any operators or functions applied to a string template within an expression should be placed outside of the string template; for example, {{foo}} > {{bar}}
or !{{bat}}
.
String templates used within expressions may not use block helpers; they may, however, use format helpers.
Note that, when doing string comparisons in expressions, it is not necessary to wrap any string template in quotes to “stringify” the output. The expression will be evaluated with the output of the string template serving as a variable; for example {{foo}} === 'bar'
or {{bat}} !== {{baz}}
.
Below are lists of operators, keywords and functions supported in expressions. If you have use cases that are not handled by these, please let us know in our forums.
Supported Operators
Expressions support the following operators:
+
(Addition)-
(Subtraction)*
(Multiplication)/
(Division)%
(Remainder)^
(Exponentiation;a ^ b
is equivalent toMath.pow(a, b)
)==
(Loose equality)===
(Strict equality)!=
(Loose inequality)!==
(Strict inequality)>
(Greater than)<
(Less than)>=
(Greater than or equal)<=
(Less than or equal)&&
(Logical AND)||
(Logical OR)!
(Logical NOT)>>
(Right bit shift)<<
(Left bit shift)
Note: In Embedded Workflows, equality operators are always treated as strict (as in, ==
behaves as ===
and !=
behaves as !==
).
Supported Keywords
Expressions have support for strings and numbers, as well as the following special keywords:
true
(boolean true)false
(boolean false)null
(JSON null)undefined
(JSON undefined)E
(e, approximately 2.718)PI
(π, approximately 3.14159)
Supported Functions
Expressions also support the following functions:
sin(radians)
Returns the sine of an angle provided in radians. See Math.sin().
cos(radians)
Returns the cosine of an angle provided in radians. See Math.cos().
tan(radians)
Returns the tangent of an angle provided in radians. See Math.tan().
asin(sinVal)
Returns the arcsine of a provided sine value. The result is in radians. See Math.asin().
acos(cosVal)
Returns the arccosine of a provided cosine value. The result is in radians. See Math.acos().
atan(tanVal)
Returns the arctangent of a provided tangent value. The result is in radians. See Math.atan().
sinh(val)
Returns the hyperbolic sine of a number. See Math.sinh().
cosh(val)
Returns the hyperbolic cosine of a number. See Math.cosh().
tanh(val)
Returns the hyperbolic tangent of a number. See Math.tanh().
asinh(val)
Returns the hyperbolic arcsine of a number. See Math.asinh().
acosh(val)
Returns the hyperbolic arccosine of a number. See Math.acosh().
atanh(val)
Returns the hyperbolic arctangent of a number. See Math.atanh().
atan2(y, x)
Returns the arctangent of the two variables y
and x
, which together represent the coordinate in the plane. The result is in radians. See Math.atan2().
sqrt(val)
Returns the square root of a number. See Math.sqrt().
log(val)
Returns the natural logarithm (base e
) of a number. See Math.log().
log10(val)
Returns the base-10 logarithm of a number.
abs(val)
Returns the absolute value of a number. See Math.abs().
ceil(val)
Returns the smallest integer greater than or equal to a number. See Math.ceil().
floor(val)
Returns the largest integer less than or equal to a number. See Math.floor().
round(val)
Rounds a number to the nearest integer. See Math.round().
trunc(val)
Truncates any fractional digits of a number, returning the integer portion. See Math.trunc().
exp(exponent)
Computes e
raised to the power of the given exponent. See Math.exp().
pow(base, exponent)
Raises a number base
to the power of exponent
. See Math.pow().
includes(collection, value)
Returns true in the following cases:
- If
collection
is a array andvalue
is equal (by deep comparison) to an entry in that array. - If
collection
is an object andvalue
is equal (by deep comparison) to one of the top-level property values. - If
collection
is a string andvalue
(when cast to a string) is equal to or matches part of that string.
Otherwise returns false.
Note: This function is not supported in Embedded Workflows.
length(val)
Computes the following string based on the type of val
:
- If
val
is an array, returns the number of items in the array. See Array.length. - If
val
is an object, returns the number of keys on the object. See Object.keys(). - If
val
is a string, returns the length of the string. See String.length. - For everything else, returns
null
.
Note: This function is not supported in Embedded Workflows.
max(a, b)
Returns the maximum of the two arguments. See Math.max().
min(a, b)
Returns the minimum of the two arguments. See Math.min().
Expression Examples
With the provided functions, keywords and operators, it is possible to build very complex expressions, such as …
sin({{ data.distance }}) >= 0.25 * PI && ({{ data.open }} !== undefined || !{{ data.closed }})
Given our example object, let’s see how these simpler expressions evaluate.
{{data.aBooleanProp}} // true
{{data.aBooleanProp}} === false // false
{{data.aNumberProp}} === 'hello' // false
{{data.aFalsyProp}} == false // true
{{data.aFalsyProp}} === false // false
!!{{data.anUndefinedProp}} // false
{{data.aNumberProp}} > 20 // true
{{data.anObject.aNestedNumber}} - {{data.aNumberProp}} // 14
{{data}} && {{data.aBooleanProp}} // true
{{data.aBooleanProp}} || {{data.aFalsyProp}} // true
{{data.aBooleanProp}} && {{data.aFalsyProp}} // false
{{data.aNumberProp}} > {{data.anObject.aNestedArray.[1]}} // true
{{data.aNumberProp}} > {{data.aStringProp}} // false
{{data.aNumberProp}} < {{data.aStringProp}} // false
{{format data.aJavascriptDateObject 'MMMM'}} === 'September' // true
{{lower data.aStringProp}} === 'Hello world' // false
{{data.anObject.aNestedArray.[1]}} / 5 <= PI // false
pow({{data.aNumberProp}}, {{data.aFalsyProp}}) === 1 // true
JSON Templates
In a few places within the Losant Platform – such as the Input Controls Block and Losant API Node, it is necessary to construct JSON objects from other data. In these instances we use JSON templates.
JSON templates can take any of the following formats (or a combination thereof):
- Valid, static JSON. e.g.
{"foo": "bar"}
,[1,2,3]
ornull
- JSON containing block helpers around keys, values or both. e.g.
{ {{#if foo}}"bar": "bat"{{else}}"baz": "bub"{{/if}} }
- JSON containing string helpers for keys or values. e.g.
{"month": "{{format date 'MMMM'}}" }
- Standard handlebars payload references, e.g.
{{data.nestedObject.nestedArray.[1]}}
Your entire input will run through Handlebars and the Losant-provided helpers. After evaluation, the result must be valid JSON. Because of this, there are a few things to keep in mind when using string templates within your JSON templates:
- Any string value being output by a string template should be wrapped in double quotes, like so:
{ "foo": "{{data.aStringProp}}" }
. - Any boolean or number value being output by a string template should not be wrapped in quotes, unless you want the value passed as a string:
{ "foo": {{data.aNumberProp}} }
. - Any objects or arrays being referenced by a string helper should always use the
jsonEncode
Handlebars helper to ensure that all string values are wrapped in quotes and all objects print as valid JSON, and should be wrapped in triple curly braces to prevent escaping of characters:{ "anObject": {{{jsonEncode data.anObjectProp}}} }
or{ "anArray": {{{jsonEncode data.anArrayProp}}} }
.
JSON Template Examples
Again, given our example object above, these JSON templates will evaluate as follows …
{ "foo": "bar", "staticNumber" : 66 }
// { "foo": "bar", "staticNumber" : 66 }
{ "myArray":
}
// { "myArray": [44, "Goodbye world", false, {"anObjectPropInAnArray": "I'm deep!"} }
{ "timestamp": , "dayOfWeek": " ", "capitalString": " " }
// { "timestamp": 1475091625000, "dayOfWeek": "Wednesday", "capitalString": "HELLO WORLD"}
{ "myString": }
// FAILS since the string is not wrapped in double quotes
// [44, "Goodbye world", false, {"anObjectPropInAnArray": "I'm deep!"}
// 20
// FAILS because the referenced value is a string, which is not valid JSON
{ "highNumber" "lowNumber" : }
// { "highNumber": 42 }
Was this page helpful?
Still looking for help? You can also search the Losant Forums or submit your question there.