Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
Celebration

Earn badges and make progress

You're on your way to the next level! Join the Kudos program to earn points and save your progress.

Deleted user Avatar
Deleted user

Level 1: Seed

25 / 150 points

Next: Root

Avatar

1 badge earned

Collect

Participate in fun challenges

Challenges come and go, but your rewards stay with you. Do more to earn more!

Challenges
Coins

Gift kudos to your peers

What goes around comes around! Share the love by gifting kudos to your peers.

Recognition
Ribbon

Rise up in the ranks

Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!

Leaderboard

Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,467,278
Community Members
 
Community Events
177
Community Groups

access a created variable's value (from a list), using it in a function...within an iterator

Edited

Hello community!

The problem I am trying to solve is to store a list of values in a created variable, and then access one of the values with a function inside of an iterator.  Has anyone done this?

For example:

  • Created variable named varList contains a list, such as dates: 2021-12-24, 2021-12-31, 2022-01-15
  • Iterator attempts to split and then use the values from the list.  To only list the values, use {{.}}
{{#varList.split(",")}}{{.}}{{/}}
  • But to use the list value in a function, the {{.}} cannot be used:
{{#varList.split(",")}}{#if(issue.created.diff(.).days.gte(0))}}+1{{/}}{{/}}
  • I wonder if there is another smart value which represents {{.}} that can be used
{{#varList.split(",")}}{#if(issue.created.diff(WHAT_TO_PUT_HERE).days.gte(0))}}+1{{/}}{{/}}
  • Other things I tried which did not help:
    • Nest the list split() to use the same list inside the iterator, accessed by get(index).  This evaluates to null, leading to the conclusion: a list cannot be accessed inside its own iterator, or that index loses meaning as a function parameter.
    • Copy the created variable list to another variable, and then try the nested list technique with one list insider of another's iterator.  This evaluates to null.
    • Format the list in the created variable as JSON, use the encode function, and then attempt to access the list by attribute name.  This evaluates to null.

The thing I cannot figure out is how to access the list iterator value.  I wonder:

  1. Is there an internal smart value name for {{.}} that can be referenced; or
  2. Can a created variable be structured as an object with attribute names (like "value"), and then split for later reference/use; or
  3. This not possible.

The only work-around I have found is to store the values in an entity property instead of the created variable.

Thanks for your ideas!

2 answers

@Bill Sheboy Any chance you figured out a solution since when this was posted?

Hi @David Pezet 

No, I did not.  Created variables are still just text, with no structure.  The closest I have gotten to this was to use a homemade, delimited variable and then a match() function later to process it.

Here is an example of that technique to find the latest sprint an issue was in: https://community.atlassian.com/t5/Jira-Software-questions/Re-How-to-create-an-automation-to-set-the-issue-s-last-s/qaq-p/2253719/comment-id/245069#M245069

Kind regards,
Bill

@Bill Sheboy Thanks for the quick reply. I've been able to flip my thinking to get away from having to reference the current element, and now run into another problem (sorry to derail the thread here). I think I run into the same problem with the string matching solution too. The issue I'm running into is that it doesn't seem I can access a variable inside the list functions (since I'm trying to iterate through two lists).

For example, I have an array of ids [1,2,3.4] stored in a variable (testArray) and an array of objects ("options") [{"id":1,"value":"text1"}, ...] returned by a web request.

If I use,

{{#webResponse.body.data.options}}
{{#if(equals(id,3))}}
{{value}}
{{/}}
{{/}}

this returns the string for the corresponding value.

My hope was to do something like,

{{#webResponse.body.data.options}}
{{#if(testArray.split(",").contains(id))}}
{{value}}
{{/}}
{{/}}

But it seems that other variables are not able to be referenced inside of the list since,

{{testArray}} 

will log the variable just fine outside the list, but

{{#webResponse.body.data.options}}
{{testArray}}
{{/}}

logs nothing ({{value}} works).

Any suggestions are greatly appreciated.

Some things to note...

  • Create variables (and even some issue fields) appear not to work in all possible functions. 
  • And...smart value, list filtering has the same challenge, as you can read in the comments to this article: https://community.atlassian.com/t5/Automation-articles/Filtering-smart-value-lists/ba-p/1827588
  • And...smart value list iterators cannot both walk the list and reference the entire list at once.  (e.g. walk the fixVersions and reference the maximum date in the iterator)
  • My hypothesis is some of those smart values passed to a functions are not evaluated and resolve to null, and then the iterator either collapses to null or returns all list items.

This symptom is the idea behind the work-around I noted: if you can create a regular expression to use in a match() then that eliminates the need to use the iterator for filtering.

For your scenario you could build the regular expression by expanding your array of id values into something like 1|2|3|4 within the expression, and use that with match as:

{{webresponse.body.data.options.match(varForYourRegularExpression)}}

Then add appropriate list and text functions to the end to process your results.

@Bill Sheboy I can't thank you enough. With the help of your info/links and a some more wrangling I was able to get a working solution. I think the biggest key bit of info was leveraging match, and that variables seem to turn everything into a string. So where referencing webhookData may keep things as object arrays, once you store it in a variable, you may have to then manipulate it again to get it back in to a form you can work with.  

In case this helps anyone else who ends up here, these were my challenges and the solutions I was able to get to work. (There very well could be better solutions, these just got me to a point where I could move on, and at least monitor for edge condition errors).

To summarize, we have an Incoming Webhook that sends info we want to store in Jira. Part of that incoming info only sends IDs, which need to be reconciled for humans. So we also have a Web Request that gets an object array of possible IDs and their Values from that external API. Since it returns the complete list of options, we only want the applicable values. Thanks to Bill's suggestion to use match(), the following is what worked for me.

1. Web Request to external API to get the complete list of possible IDs and their values.

2. Create Variable for the regular expression to match the IDs that were in the Incoming Webhook data.

((?<=label=)((?!label=).)+(?=[,][ ]id=({{#webhookData.someArrayID.split(",")}}{{.}}{{^last}}|{{/}}{{/}})}))

3. Store the results in Jira field (in this case a checkbox field).

{
"fields": {
"customfield_12345": [{{webResponse.body.data.options.asJsonStringArray.match(rx).asJsonObject("value")}}]
}
}

Another part of our challenge was that we also needed to pass some of this information to another automation. Since I couldn't find a way to simply pass the original webhookData to the next automation, I had to recreate the necessary data as Custom Data in the web request (e.g., { {"newObjectName" : "{{webhookData.something}}" } } ). So while working with the original external API data on the first incoming webhook I was able to use 

{{webResponse.body.data.options.asJsonStringArray.match(rx).asJsonObject("value")}}

(rx being the regular expression variable), I would need to pass it to the next automation already formatted for the storing in the Jira issue as 

{{webResponse.body.data.options.asJsonStringArray.match(rx).asJsonObject("value").jsonEncode}}

so it could then be put back into an array when setting the Jira value 

"customfield_12345": [{{webhookData.newObjectName}}]

--There is probably a solution for passing just that match results (not formatted asJsonObject), but I experienced issues between needing to pass jsonEncode 'd  and dealing with string vs arrays on the other side, I decided to skip figuring this out.

Another thing to watch out for was making sure to group (extra wrapping parentheses) the regular expressions results so they came through correctly. Also, instead of custom formatting the string to be evaluated by the regex, I decided to use a regex that worked with the json formatted string using lookaheads/behinds. This is what ended up working for me and the match would output an array of any of the matches.

((?<=value=)((?!value=).)+(?=[,][ ]id=({{#webhookData.someArrayID.split(",")}}{{.}}{{^last}}|{{/}}{{/}})})) 

Hope this helps. Feedback welcome. I look forward to a future where created variables can be used inside lists  and current list values could be referenced as something like {{this}} instead of {{.}} for simpler a solutions...

0 votes
Darryl Lee Community Leader Jan 26, 2022

This is not an actual answer, but commiseration. I went down a rabbit-hole trying to find an answer to Perla's additional request to iterate with a counter value. 

I tried to represent {{counterValues}} in all kinds of list formats, but got nowhere fast.

I think I even tried splitting "1,2,3,4" into its own variable, hoping it would "magically" convert to a list, but Automation did not like that.

Now that I've come back to the question, I see your very clever usage of the index value. That is incredibly SLICK, as I could not for the life of me figure out how to get array values into such a loop.

We really could use the ability to properly define arrays and then some functions for them. When you see something like .split you just naturally think there should be a way to go the other direction.

Suggest an answer

Log in or Sign up to answer
TAGS

Atlassian Community Events