Accessing a Variable

I am getting the following values in a variable called data. What would be the right way of getting the values ?

{“dates”:[“2021-04-21T07:25:06.000Z”,“2021-04-22T07:25:06.000Z”]}

I would like to get the date part i.e. date 1 as 21-Apr-2021 and date 2 as 22-Apr-2021. I think the formatting can be done using mustache.

This is not working

{{data.dates[1] | date:“yyyy-MM-dd”}}

I am getting error,

com.samskivert.mustache.MustacheException$Context: No method or field with name ‘data.dates[1] | date:“yyyy-MM-dd”’

Thank you

I think I can use a combination of the date conversion function along with the temporal expression month of year() to get the month name but i would need to get the data out of that array first.

Edit: I tried accessing using data.dates[0] but same error as in my first message

Hi @Bisoux,

you’re close. Using the date() function is a good idea.

Applying the function to the list returns date values.

for d in dates return date(date and time(d))

image

To format the date, you can use the month of year() function and access the parts of the date value. You can put this part in an inline context to make it more readable.

for d in dates return { 
  date: date(date and time(d)), 
  day: string(date.day),
  month: month of year(date),
  year: string(date.year),
  formatted: day + "-" + month + "-" + year
}.formatted

image

Final part, use the substring() function to limit the month to three characters.

for d in dates return { 
  date: date(date and time(d)), 
  day: string(date.day),
  month: substring(month of year(date), 1, 3),
  year: string(date.year),
  formatted: day + "-" + month + "-" + year
}.formatted

image

Does this help you?

Best regards,
Philipp

3 Likes

Thank you very much @philipp.ossler . I will give this a go. Giving slightly more context now for the use case which I should have done when posting the question.

So the plan to show these date values in an email template that goes out to the user. Right now I am using mustahce script to set up my email template with data from the workflow. Those date values will be displayed in the form of a From date - To date in the template.

The workflow looks like this,

A message is received from the ui with a data payload. From what I can gather from you is that I would have to parse the dates in a separate service task and pass on the value to the Compose Template task where I have my mustache script ? I am using the Compose Template Task in other workflows where i preformat the date as I get the values from a database, no issues there, but in this case I can only get the dates from the start message.

In my Get date service task I have the following setup,

getdate

I have put the script in variable assignment value. I am getting the bellow error

java.lang.RuntimeException: Failed to evaluate script ‘for d in leavedates return { date: date(date and time(d)), day: string(date.day), month: substring(month of year(date), 1, 3), year: string(date.year), formatted: day + “-” + month + “-” + year }.formatted’ (feel) at io.zeebe.script.ScriptEvaluator.evalWithScriptEngine(ScriptEvaluator.java:60) at io.zeebe.script.ScriptEvaluator.evaluate(ScriptEvaluator.java:42) at io.zeebe.script.ScriptJobHandler.handle(ScriptJobHandler.java:59) at jdk.internal.reflect.GeneratedMethodAccessor32.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at io.zeebe.spring.client.bean.MethodInfo.invoke(MethodInfo.java:31) at io.zeebe.spring.client.config.processor.ZeebeWorkerPostProcessor.lambda$null$1(ZeebeWorkerPostProcessor.java:49) at io.zeebe.client.impl.worker.JobRunnableFactory.executeJob(JobRunnableFactory.java:44) at io.zeebe.client.impl.worker.JobRunnableFactory.lambda$create$0(JobRunnableFactory.java:39) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: javax.script.ScriptException: failed to parse expression ‘for d in leavedates return { date: date(date and time(d)), day: string(date.day), month: substring(month of year(date), 1, 3), year: string(date.year), formatted: day + “-” + month + “-” + year }.formatted’: [1.107] error: ‘}’ expected but ‘(’ found for d in leavedates return { date: date(date and time(d)), day: string(date.day), month: substring(month of year(date), 1, 3), year: string(date.year), formatted: day + “-” + month + “-” + year }.formatted ^ at org.camunda.feel.impl.script.FeelScriptEngine.handleEvaluationResult(FeelScriptEngine.scala:87) at org.camunda.feel.impl.script.FeelScriptEngine.eval(FeelScriptEngine.scala:61) at org.camunda.feel.impl.script.FeelScriptEngine.eval$(FeelScriptEngine.scala:57) at org.camunda.feel.impl.script.FeelExpressionScriptEngine.eval(FeelExpressionScriptEngine.scala:22) at io.zeebe.script.ScriptEvaluator.eval(ScriptEvaluator.java:71) at io.zeebe.script.ScriptEvaluator.evalWithScriptEngine(ScriptEvaluator.java:56) … 15 more

It seems that you use the Zeebe script task worker to evaluate the FEEL expression. Maybe, the worker uses an older version of the FEEL engine. It should work with the latest version of the worker.

However, you could also use the FEEL expression in the input mapping of the service task Compose Template task directly.

Yes we are using the script task worker to evaluate the feel expression. I don’t think I can use the feel expression on the Compose Template task as I already have a mustache script set up on it.

The below code should give me that list,

for d in dates return {
date: date(date and time(d)),
day: string(date.day),
month: substring(month of year(date), 1, 3),
year: string(date.year),
formatted: day + “-” + month + “-” + year
}.formatted

i.e.

List(21-Apr-2021,22-Apr-2021)

Beginners question but how would i get 21-Apr-2021 out of that ?

Many Thanks

You can access the element by its index, starting from 1.

fromDate[1]
// "21-Apr-2021"

fromDate[2]
// "22-Apr-2021"

You don’t need to but you could use input mappings on the service task. The mappings are applied before the job is created from the job worker. They create a new local variable in the scope of the task. Read more about it here: Variables | Camunda 8 Docs

1 Like

So this setup i tried earlier should work. I literally copied the script, just changed the local variable name.

getdate

The error could be as you said, the worker uses an older version of the FEEL engine. Unfortunaltely not much I can do about that as that’s our dev’s department role. I am the B.A :nerd_face:

Not sure this will help but the leavedates variable shows this,

Thanks again

@philipp.ossler I am tantalizingly close

Thats what my input varaible looks like now,

inputOutput

In my mustache script I have this,

Template

which when the workflow completes looks like the below in the template,

Template-Output

Close to what I want it to look like, but when I did fromDates[1] in the template mustache script i.e. {{fromDate[1]}} it behaves as would be expected and gives an error that fromDate[1] is not found.

Assuming that the Mustache script references the variables fromDate and toDate, you could define the following 3 input mappings on the task:

formattedDates
= for d in dates return {
date: date(date and time(d)),
day: string(date.day),
month: substring(month of year(date), 1, 3),
year: string(date.year),
formatted: day + “-” + month + “-” + year
}.formatted

fromDate
= formattedDates[1]

toDate 
= formattedDates[2]
1 Like

Works perfectly! Thank you so much @philipp.ossler

1 Like