get emails for last x number of hours in logic app - azure-logic-apps

I am using "get emails v3" action in "outlook.com" for logic apps. I want to search emails based on subject filters in todays date only. I want following search criteria where I want emails between two times.
((receivedDateTime:#{utcNow()})) BETWEEN (receivedDateTime:#{addToTime(utcNow(), 1, 'Day')})
Is there any way to do that?

After reproducing it was clear that this is because of the format of receivedDateTime is not as same as the format of utcNow(). To achieve your requirement, you need to compare the dates in same format using condition. Below is how I to achieve your requirement using condition action.
Left side Condition
formatDateTime(items('For_each_2')?['receivedDateTime'],'dd/MM/yyyy')
Right side Condition
formatDateTime(addDays(utcNow(), -1), 'dd/MM/yyyy')
Here is the complete flow of my logic app
RESULTS:
Below is the code view of my Logic App
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each_2": {
"actions": {
"Condition": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "Email",
"value": "#items('For_each_2')"
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"expression": {
"and": [
{
"greaterOrEquals": [
"#formatDateTime(items('For_each_2')?['receivedDateTime'],'dd/MM/yyyy')",
"#formatDateTime(addDays(utcNow(), -1), 'dd/MM/yyyy')"
]
},
{
"lessOrEquals": [
"#formatDateTime(items('For_each_2')?['receivedDateTime'],'dd/MM/yyyy')",
"#formatDateTime(utcNow(),'MM/dd/yyyy')"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#body('Get_emails_(V3)')?['value']",
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Foreach"
},
"Get_emails_(V3)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "get",
"path": "/v3/Mail",
"queries": {
"fetchOnlyFlagged": false,
"fetchOnlyUnread": false,
"fetchOnlyWithAttachment": false,
"folderPath": "Inbox",
"importance": "Any",
"includeAttachments": false
}
},
"runAfter": {},
"type": "ApiConnection"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "Email",
"type": "array"
}
]
},
"runAfter": {
"Get_emails_(V3)": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"office365": {
"connectionId": "/subscriptions/<SUBID>/resourceGroups/<RG>/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/<SUBID>/providers/Microsoft.Web/locations/centralus/managedApis/office365"
}
}
}
}
}

If I've understood you correctly then this is the sort approach you need to take.
There's an additional parameter to that connector called Search Query.
In there, you can put an expression that looks like the following ...
received>#{formatDateTime(addDays(utcNow(), -1), 'MM/dd/yyyy')}
You're close, if you look at the doco though, the name of the field is different to what comes back in the response.
https://learn.microsoft.com/en-gb/graph/search-query-parameter
You may just need to play around with the formula to give you exactly what you want given the response is all in UTC. I think -1 day is the easiest but it may not be perfect for you.

Related

Azure Logic apps - output array in email body

I have trouble using my array variable in my V2 email in Logic apps. I would like to output my array in the email body. For example if my array is ["1","2",3"]. Im want each value on its own row.
1
2
3
I have 2 issues, outputting my array in the email body(only strings showing in the dynamic menu) and making each value on a row.
After reproducing from my end, I could able to achieve your requirement by replacing "," with "< br>< br>" while sending the email using Send an email (V2) action. Below is the expression that worked for me.
replace(string(variables('SampleArray')),',','<br><br>')
Here is the flow of my Logic App
Result in my Inbox:
To reproduce the same, you can use below codeview in your logicapp
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"SampleArray": {
"inputs": {
"variables": [
{
"name": "SampleArray",
"type": "array",
"value": [
1,
2,
3
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Send_an_email_(V2)": {
"inputs": {
"body": {
"Body": "<p>#{replace(string(variables('SampleArray')),',','<br><br>')}</p>",
"Importance": "Normal",
"Subject": "Sample",
"To": "<YOUR-EMAIL>"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"operationOptions": "DisableAutomaticDecompression",
"runAfter": {
"SampleArray": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"office365": {
"connectionId": "/subscriptions/<SUB-ID>/resourceGroups/<RG>/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/<SUB-ID>/providers/Microsoft.Web/locations/centralus/managedApis/office365"
}
}
}
}
}

How to check json and do filtering in Logic App

In my Logic App one of the action item gives me Json value as like this . This is recorded in compose action.
{
"device1": 24,
"device2": 25,
"device3": 26
}
I would like to take only that device name and value whose value is equal to and above 25 (in this case device2 and device3)and then pass that value in subsequent method like creating and sending an alert message for each device name whose value is 25 or more.
How can I do that in logic app?
Here is one of the workaround that worked for me. In order to filter the Json in well defined, easy format (i.e., devices whose value is greater than 25) and also for future use, we need to convert the json of format
{
"device1": 24,
"device2": 25,
"device3": 26
}
to
[
{
"deviceName": "\"device1\"",
"value": "24"
},
{
"deviceName": "\"device3\"",
"value": "26"
},
{
"deviceName": "\"device2\"",
"value": "25"
}
]
We first need to convert the Json into array. This can be done in 2 ways
Way -1 (using subString())
syntax in Method 1 step 1
substring(string(outputs('Compose')),1,sub(lastIndexOf(string(outputs('Compose')),'}'),1))
syntax in Method 1 step 2
array(split(string(outputs('Convert_To_Array_Method_1_step_1')),','))
Way -2 (using replace())
syntax in Method 2 step 1
replace(string(outputs('Compose')),'{','[')
syntax in Method 2 step 2
replace(string(outputs('Convert_To_Array_Method_2_step_1')),'}',']')
output:
You need to initialize an array variable in order to store the resultant json.
We can now extract the values inside the json by taking either of syntax in Method 1 step 2or syntax in Method 2 step 2 outputs in For each connector.
In Extract values compose connector I'm trying to extract the values of the devices by taking substring expression.
syntax in Extract values
substring(item(),add(indexOf(item(),':'),1),sub(length(item()),add(indexOf(item(),':'),1)))
Here I'm just extracting the values that are there after ':'.
The same goes with device names too. I'm extracting the device names that are there from index 0 to ':'.
syntax in Formatted JSON
{
"inputs": {
"deviceName": "#substring(item(), 0, indexOf(item(), ':'))",
"value": "#outputs('Extract_Value')"
}
}
Then lastly I'm storing the resultant Formatted Json to a variable.
output:
Now I'm just parsing the the Formatted variable which gives me the results of device name and value.
In the next step I'm using Condition connector to check if the value greater than or equal to 25
syntax in Condition
int(items('For_each_2')['value'])
if the condition is true then it stores the value to Required Values.
output:
Here is the code view of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"device1": 24,
"device2": 25,
"device3": 26
},
"runAfter": {},
"type": "Compose"
},
"Convert_To_Array_Method_1_step_1": {
"inputs": "#substring(string(outputs('Compose')),1,sub(lastIndexOf(string(outputs('Compose')),'}'),1))",
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_To_Array_Method_1_step_2": {
"inputs": "#array(split(string(outputs('Convert_To_Array_Method_1_step_1')),','))",
"runAfter": {
"Convert_To_Array_Method_1_step_1": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_To_Array_Method_2_step_1": {
"inputs": "#replace(string(outputs('Compose')),'{','[')",
"runAfter": {
"Convert_To_Array_Method_1_step_2": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_To_Array_Method_2_step_2": {
"inputs": "#replace(string(outputs('Convert_To_Array_Method_2_step_1')),'}',']')",
"runAfter": {
"Convert_To_Array_Method_2_step_1": [
"Succeeded"
]
},
"type": "Compose"
},
"Final_Formated_JSON": {
"inputs": "#variables('formatedArray')",
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Compose"
},
"Final_Values": {
"inputs": "#variables('Required Values')",
"runAfter": {
"For_each_2": [
"Succeeded"
]
},
"type": "Compose"
},
"For_each": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "formatedArray",
"value": "#outputs('Formated_JSON')"
},
"runAfter": {
"Formated_JSON": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Extract_Value": {
"inputs": "#substring(item(),add(indexOf(item(),':'),1),sub(length(item()),add(indexOf(item(),':'),1)))",
"runAfter": {},
"type": "Compose"
},
"Formated_JSON": {
"inputs": {
"deviceName": "#substring(item(), 0, indexOf(item(), ':'))",
"value": "#outputs('Extract_Value')"
},
"runAfter": {
"Extract_Value": [
"Succeeded"
]
},
"type": "Compose"
}
},
"foreach": "#outputs('Convert_To_Array_Method_1_step_2')",
"runAfter": {
"Initialize_variable_to_store_the_formatted_Json_": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_each_2": {
"actions": {
"Condition": {
"actions": {
"Append_to_array_variable_2": {
"inputs": {
"name": "Required Values",
"value": "#items('For_each_2')"
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"expression": {
"and": [
{
"greaterOrEquals": [
"#int(items('For_each_2')['value'])",
25
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#body('Parse_JSON')",
"runAfter": {
"Initialize_variable_to_store_required_values": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable_to_store_required_values": {
"inputs": {
"variables": [
{
"name": "Required Values",
"type": "array"
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_to_store_the_formatted_Json_": {
"inputs": {
"variables": [
{
"name": "formatedArray",
"type": "array"
}
]
},
"runAfter": {
"Convert_To_Array_Method_2_step_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#variables('formatedArray')",
"schema": {
"items": {
"properties": {
"deviceName": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"deviceName",
"value"
],
"type": "object"
},
"type": "array"
}
},
"runAfter": {
"Final_Formated_JSON": [
"Succeeded"
]
},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
In these situations, I find it much easier to write an Azure Function that does the work.
It'll ultimately keep your LogicApp cleaner than it would otherwise be with a whole heap of functionality to work around (perceived) limitations.
In the Azure Portal, go to the Azure Functions blade and create a new .NET HttpTrigger function with the following code ...
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
string thresholdString = req.Query["threshold"];
var threshold = int.Parse(thresholdString);
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var jObject = JObject.Parse(requestBody);
var filteredObject = new JObject(jObject.Properties().ToList().Where(x => (int)x.Value >= threshold));
return new OkObjectResult(filteredObject);
}
... it assumes the JSON you pass in is along the lines of what you provided so be aware of that.
Now call it from your LogicApp like and you'll get the response you desire ...
Action
Result

Convert CSV file as array in logic apps

I want to read CSV file as array in logic apps. I didn't find any documents related to it. Any help on this would be appreciated. Thank you!
Based on your question here are few arounds that we can try below either way for 2 different outputs.
READ EACH OBJECT CSV FILE AS ARRAY OBJECT:
We can use split and add the output of the compose connector into Array by adding 'Initialise Variable' Connector and for converting each word into array variable we need to add for each connector inside another for each connector to iterate the items inside the CSV file then with a split variable inside the inner for each connector having split(item(),',') expression.
READ EACH ROW IN CSV FILE AS AN ARRAY:
We can use Plumsail's Parse CSV connector in order to convert each CSV row as an array considering headers in the CSV file.
Here are the screenshots for your reference
Expression in compose connector
split(body('Get_blob_content_(V2)'),'\n')
Expression in For each 2 connector
split(item(),',')
Note: Make sure you go to your code view and change the expression in your split from
split(body('Get_blob_content_(V2)'),'\\n') to split(body('Get_blob_content_(V2)'),'\n') as when we are writing the expression for this it first takes '\n' as string and adds another "" to the expression.
Here is the code view of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "#split(body('Get_blob_content_(V2)'),'\n')",
"runAfter": {
"Get_blob_content_(V2)": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_2": {
"inputs": "#variables('array1')",
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Compose"
},
"For_each": {
"actions": {
"For_each_2": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "array1",
"value": "#items('For_each_2')"
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"foreach": "#split(item(),',')",
"runAfter": {},
"type": "Foreach"
}
},
"foreach": "#outputs('Compose')",
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Foreach"
},
"Get_blob_content_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob_1']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files/#{encodeURIComponent(encodeURIComponent('JTJmY29udGFpbmVyMjQlMmZkYXRhLWFydGljbGUuY3N2'))}/content",
"queries": {
"inferContentType": true
}
},
"metadata": {
"JTJmY29udGFpbmVyMjQlMmZkYXRhLWFydGljbGUuY3N2": "/container24/data-article.csv"
},
"runAfter": {},
"type": "ApiConnection"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "array1",
"type": "array",
"value": "#outputs('Compose')"
}
]
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_CSV": {
"inputs": {
"body": {
"content": "#{base64(body('Get_blob_content_(V2)'))}",
"headers": "url,user_id,token_id,username,password"
},
"host": {
"connection": {
"name": "#parameters('$connections')['plumsail']['connectionId']"
}
},
"method": "post",
"path": "/flow/v1/Documents/jobs/ParseCsv"
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob_1": {
"connectionId": "/subscriptions/<Your subscription>/resourceGroups<Your resourec group >/providers/Microsoft.Web/connections/azureblob-1",
"connectionName": "azureblob-1",
"id": "/subscriptions/<Your subscription>/providers/Microsoft.Web/locations/northcentralus/managedApis/azureblob"
},
"plumsail": {
"connectionId": "/subscriptions/<Your subscription>/resourceGroups/<Your resourec group >/providers/Microsoft.Web/connections/plumsail",
"connectionName": "plumsail",
"id": "/subscriptions/<Your subscription>/providers/Microsoft.Web/locations/northcentralus/managedApis/plumsail"
}
}
}
}
}
REFERENCES:
Convert CSV elements into a single Array using Azure Logic Apps - Stack Overflow

How to display array in Slack Webhook of Azure Logic Apps?

I have LogicApps. It receives property ListOfNames array in HTTP request.
I have difficulty to display correctly in Slack webhook. How to format body?
Current message displayed in Slack:
ListOfNames:
["Name1 \n","Name2\n","Name3\n"]
Target message in slack:
ListOfNames:
Name1
Name2
Name3
I tried Split:
Code: No errors, but don't array items listed correctly in message:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "#split(string(triggerBody()?['ListOfTesNames']),'\\n') ",
"runAfter": {},
"type": "Compose"
},
"HTTP_Webhook": {
"inputs": {
"subscribe": {
"body": {
"blocks": [
{
"text": {
"text": "*[dev] Testing:* \n ListOfTestNames #{outputs('Compose')} ",
"type": "mrkdwn"
},
"type": "section"
},
{
"text": {
"text": "Please check test results from database ",
"type": "mrkdwn"
},
"type": "section"
}
]
},
"method": "POST",
"uri": "https://hooks.slack.com/services/1111111111111111111111"
},
"unsubscribe": {}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"runtimeConfiguration": {
"staticResult": {
"name": "HTTP_Webhook0",
"staticResultOptions": "Disabled"
}
},
"type": "HttpWebhook"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"staticResults": {
"HTTP_Webhook0": {
"outputs": {
"headers": {},
"statusCode": "OK"
},
"status": "Succeeded"
}
},
"triggers": {
"manual": {
"inputs": {
"method": "POST",
"schema": {
"properties": {
"ListOfTestNames": {
"type": "array"
}
},
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
You can add a compose connector before the webhook connector and use split functionality which gives the right format and then add the output of the compose connector to your webhook connector.
Here is a screenshot for your reference:
Note: Make sure you modify the expression in your split from compose connector as split(triggerBody()?['ListOfFiles'],'\n') to split(triggerBody()?['ListOfFiles'],'\n') because when we write the expression for this, it first takes '\n' as a string and then adds another ''.
Below is the split expression in compose connector:
split(triggerBody()?['ListOfFiles'],'
')
Updated Answer
As we are retrieving an array and passing it to the body of text it is adding the extra characters to it. We have created a new Logic App and added each item that we are retrieving to a variable and finally added that variable to the Webhook body.
Here is the screenshot of the logic app
Here is my code view
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"For_each_2": {
"actions": {
"Append_to_string_variable": {
"inputs": {
"name": "ListOfFilesFinal",
"value": "#{items('For_each_2')},"
},
"runAfter": {},
"type": "AppendToStringVariable"
}
},
"foreach": "#split(item(),',')",
"runAfter": {},
"type": "Foreach"
}
},
"foreach": "#triggerBody()?['ListOfFiles']",
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Foreach"
},
"HTTP_Webhook": {
"inputs": {
"subscribe": {
"body": {
"blocks": [
{
"text": {
"text": "*[dev] Testing: * \n ListOfTestNames : #{variables('ListOfFilesFinal')} ",
"type": "mrkdwn"
},
"type": "section"
},
{
"text": {
"text": "Please check test results from database ",
"type": "mrkdwn"
},
"type": "section"
}
]
},
"method": "POST",
"uri": "#listCallbackUrl()"
},
"unsubscribe": {}
},
"runAfter": {
"For_each": [
"Succeeded"
]
},
"runtimeConfiguration": {
"staticResult": {
"name": "HTTP_Webhook0",
"staticResultOptions": "Disabled"
}
},
"type": "HttpWebhook"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "ListOfFilesFinal",
"type": "string"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"staticResults": {
"HTTP_Webhook0": {
"outputs": {
"headers": {},
"statusCode": "OK"
},
"status": "Succeeded"
}
},
"triggers": {
"manual": {
"inputs": {
"method": "POST",
"schema": {
"properties": {
"ListOfFiles": {
"type": "array"
}
},
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}

Azure Logic App Condition does not work in loop if based on changing values

I need to write a simple LogicApp that connects to a http endpoint, receives some JSON, loops though the JSON message and submits it to a different http endpoint in chunks based on a value in the message.
In doing this I've come to the conclusion that Conditions inside For Each loop always evaluate the conditions before the loop and executes the path that matched the result before the loop, even though the result should have changed as the some variables have been updated in the loop.
I've managed to illustrate the problem with the below example.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "#variables('TestStr')",
"runAfter": {
"Compose_3": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_3": {
"inputs": "#variables('TestArray')",
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Compose"
},
"For_each": {
"actions": {
"Compose_2": {
"inputs": "#variables('TestArray')",
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "Compose"
},
"Condition": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "TestArray",
"value": "#items('For_each')"
},
"runAfter": {},
"type": "AppendToArrayVariable"
},
"Set_variable_2": {
"inputs": {
"name": "TestStr",
"value": "XXXX"
},
"runAfter": {
"Append_to_array_variable": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"else": {
"actions": {
"Set_variable": {
"inputs": {
"name": "TestStr",
"value": "not"
},
"runAfter": {},
"type": "SetVariable"
}
}
},
"expression": {
"and": [
{
"equals": [
"#variables('TestStr')",
"BlankValue"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#variables('FullArray')",
"runAfter": {
"Initialize_variable_3": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "TestStr",
"type": "String",
"value": "BlankValue"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "TestArray",
"type": "Array"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_3": {
"inputs": {
"variables": [
{
"name": "FullArray",
"type": "Array",
"value": [
{
"key": "value1"
},
{
"key": "value2"
},
{
"key": "value3"
}
]
}
]
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Month",
"interval": 3
},
"type": "Recurrence"
}
}
}
}
I would expect the below LogicApp to execute the loop three times, every time evaluate the condition and execute array insert only once, with the TestArray containing one entry of
{
"key":"value1"
}
and string TestStr having value of 'not'
But the actual results seem to differ - TestArray contains all three entries from FullArray and TestStr is 'XXXX'
What am I missing here? Are there any workarounds?
I've discovered the reason for this behaviour. Posting here if anyone comes across this in the future.
For_each loops are executed in parallel by default. That is why the conditions are evaluated for all iterations before the loop starts.
There is a way of switching this off - in the Settings you can switch on concurrency control and set parallelism to 1

Resources