Test action outputs length - azure-logic-apps

In my Logic App workflow, I'm trying to evaluate a condition for the previous action outputs array.
My condition expression
#less(action('Get_items').outputs.length, 1)
results in error
action 'Item_found' completed with status 'Failed' and code 'BadRequest'.
The same happens for
#greater(action('Get_items').outputs.length, 1)
as well as
#empty(action('Get_items').outputs)
What am I doing wrong here?
Background: The action('Get_items') is query retrieving items from a SPO site list using a Filter Query.
The action succeeds but the App Run Trace doesn't show any details on the outputs, in this case the expected empty array.

I managed to achieve the desired condition evaluation by correctly accessing the array the same way a for-each action does:
#empty(body('Get_items')['value'])
The documentation doesn't give a hint on this.

Accepted solution was not working for me for CDS entities, so I have solved it by using such condition:
#length(body('Get_items')['value'])
If I understand correctly it is converting array to string and empty array is converted to [], so you just have to check if the output of query is more than 2, then it means Get_Items is not empty.

Related

How do I select whether the routine continues based on the participant's response?

I want to create an experiment in PsychoPy Builder that conditionally shows a second routine to participants based on their keyboard response.
In the task, I have a loop that first goes through a routine where participants have three options to respond ('left','right','down') and only if they select 'left', regardless of the correct answer, should they see a second routine that asks a follow-up question to respond to. The loop should then restart with routine 1 each time.
I've tried using bits of code in the "begin experiment" section as such:
if response.key=='left':
continueRoutine=True
elif response.key!='left':
continueRoutine=False
But here I get an error saying response.key is not defined.
Assuming your keyboard component is actually called response, the attribute you are looking for is called response.keys. It is pluralised as it returns a list rather than a single value. This is because it is capable of storing multiple keypresses. Even if you only specify a single response, it will still be returned as a list containing just that single response (e.g. ['left'] rather than 'left'). So you either need to extract just one element from that list (e.g. response.keys[0]) and test against that, or use a construction like if 'left' in response.keys to check inside the list.
Secondly, you don't need to have a check that assigns True to continueRoutine, as it defaults to being True at the beginning of a routine. So it is only setting it to False that results in any action. So you could simply do something like this:
if not 'left' in response.keys:
continueRoutine = False
Lastly, for PsychoPy-specific questions, you might get better support via the dedicated forum at https://discourse.psychopy.org as it allows for more to-and-fro discussion than the single question/answer structure here at SO.

Check if Json Array contains objects in Logic App

I am trying this out but I cant seem to get it to work.
In a Condition connector I'm doing this:
#contains(json(body('ParseCustomerDeltaXML')).newMembers[0], 'Member')
but i cant get it to work.
If it contains members it says true.
But if not i get an error:
InvalidTemplate. Unable to process template language expressions for action 'Condition' at line '1' and column '2706': 'The template language expression 'equals(json(body('ParseCustomerDeltaXML')).newMembers[0], null)' cannot be evaluated because array index '0' cannot be selected from empty array. Please see https://aka.ms/logicexpressions for usage details.'.
As indicated by the error message, the array you are trying to reference the first item of is empty. You want to make use of the safe dereference operator .?
Suppose newMembers is an empty array. Then newMembers[0] would fail, but newMembers?[0] would succeed (and return null).
In the specific scenario you are describing, you may need to use a nested condition as well (i.e. first check if newMembers is non-empty, and then check for membership).
To check for emptiness you can use the #empty() expression.
In my example I should check is element empty before fetching street data from element.
This works:
if(empty(body('Parse_JSON')?['results'][0]['addresses']), '', body('Parse_JSON')?['results'][0]['addresses'][0]['street'])
and this works too:
if(contains(['addresses'], ['addresses']?[0]), 'Do something', 'Or do this thing')
Hope that will help someone.

How to assert an actual value with two different expected values

I'm writing a protractor test which asserts a URL against two different browser URLs.
I tried using toMatch with a regular expression but I get an error.
Is it possible to assert an actual string value against 2 or more expected string values and see if it is equal to any of them?
expect(url1).toMatch(/this.url|www.google.com/);
Sounds like you want to use toContain() which works for finding an item in an array. So switch your assertion around because you want to pass it an array of URLs [this.url, 'www.google.com'] and assert that it will contain url1.
expect([this.url, 'www.google.com']).toContain(url1);
Note: While this should work, personally I don't like to have my values on the receiving end of the assertion i.e. toContain(url1), I would rather that be passed first expect(url1).... However, in the end it's still asserting actual vs expected values so not a huge deal in my opinion.
https://jasmine.github.io/2.0/introduction.html

Identify one particular field with RegEx

Apologies for the basic question but I'm new to regular expressions and am really struggling to find a solution to the problem I am facing.
I am trying to pull out a particular field from a json response dynamically, which can change each time I call it.
The response is:
[{"colorPartNumber":"10045112022164298","skuPartNumber":"0400218072057","productColor":{"identifier":"Dark blue","label":"Dark blue","hex":"#0000A0"},"productSize":{"identifier":"0","label":"0","name":"Designer","scaleLabel":"apparel-wmn","schema":{"name":"UK","labels":["8"]}},"soldOut":true,"onlyOneLeft":false,"limitedAvailability":false,"preorder":false,"comingSoon":false,"visible":true,"displayable":true,"buyable":false,"availableInPhysicalStore":false,"expectedShippingDate":null},{"colorPartNumber":"10045112022164298","skuPartNumber":"0400094632819","productColor":{"identifier":"Dark blue","label":"Dark blue","hex":"#0000A0"},"productSize":{"identifier":"1","label":"1","name":"Designer","scaleLabel":"apparel-wmn","schema":{"name":"UK","labels":["10"]}},"soldOut":true,"onlyOneLeft":false,"limitedAvailability":false,"preorder":false,"comingSoon":false,"visible":true,"displayable":true,"buyable":false,"availableInPhysicalStore":false,"expectedShippingDate":null},{"colorPartNumber":"10045112022164298","skuPartNumber":"0400218072040","productColor":{"identifier":"Dark blue","label":"Dark blue","hex":"#0000A0"},"productSize":{"identifier":"2","label":"2","name":"Designer","scaleLabel":"apparel-wmn","schema":{"name":"UK","labels":["12"]}},"soldOut":true,"onlyOneLeft":false,"limitedAvailability":false,"preorder":false,"comingSoon":false,"visible":true,"displayable":true,"buyable":false,"availableInPhysicalStore":false,"expectedShippingDate":null},{"colorPartNumber":"10045112022164298","skuPartNumber":"0400468014814","productColor":{"identifier":"Dark blue","label":"Dark blue","hex":"#0000A0"},"productSize":{"identifier":"3","label":"3","name":"Designer","scaleLabel":"apparel-wmn","schema":{"name":"UK","labels":["14"]}},"soldOut":false,"onlyOneLeft":true,"limitedAvailability":false,"preorder":false,"comingSoon":false,"visible":true,"displayable":true,"buyable":true,"availableInPhysicalStore":false,"expectedShippingDate":null}]
I am trying to pull out the skuPartNumber, but only when the "buyable" value is set to true.
Every thing I try I cannot seem to get just this one value :(
So in the example above the only value I want to pull out is 0400468014814.
This json is dynamic so there could be 100 values coming back, but the principle is the same.
One example of a failed attempt is skuPartNumber(.*?)"buyable":true, which only gives me the very first value (0400218072057), which is wrong.
Once again sorry for the basic question.
Try the following regular expression:
\"skuPartNumber\":\"(\d+)\"(?:[^}]*?\}){3}[^}]*?\"buyable\":true
Your answer is in the first match group.

Append to JSON array within an JSON array ColdFusion

This is a follow up question to: Append to JSON array with ColdFusion, taking Null values into consideration?
That question was answered yesterday and worked perfectly (Thank you Kevin B. and Leigh!). However, the application I am pulling my JSON data from threw me a curve ball this morning. Sometimes, depending on the data I am requesting, it returns the entire JSON as an array like this:
[
{
"loginHosts": [
"server1.example.com"
],
"sudoHosts": [
"server1.example.com"
],
"CPG": [
"my_group"
],
"mail": "myuser#example.com",
"loginShell": "/bin/bash"
}
]
I don't know why that application does this. If I knew this was a possibility I would have added that information to my previous question, my apologies.
My attempts to find a solution lead me here first: Using JSON Data with Coldfusion . Looping over the JSON array as a collection seemed to work, but only if none of the array values were Null. I thought using this code, as in the previous question, would work if I used it for all the JSON fields:
<cfif NOT structKeyExists(myStruct, 'sudoHosts') OR NOT isArray(myStruct.sudoHosts)>
<cfset myStruct.sudoHosts = []>
</cfif>
This was not the case. I continually get:
Error: Can't cast Complex Object Type Array to String
Looking through the debug output, Lucee did throw this out: string Use Built-In-Function "serialize(Array):String" to create a String from Array. I did more digging and found this article: Railo tip: store complex data by using serialize(data). Sadly, Null values have struck again. Also, my understanding is serialize() is similar to evaluate(), and not recommended.
I will continue looking for a solution but any help is, as always, greatly appreciated!
-- EDIT --
I came across this thread: ColdFusion JSON object vs array of objects. I noticed the JSON in the question is an ARRAY [], and I applied the answer to my code, but am still running into the Null problem. I guess I don't know how to check for nested Null values. :(
Take it one step at a time.
Ideally you should determine why the response differs. Since you say those differences usually correspond to something different in your request, that strongly suggests you may be overlooking (or possibly misunderstanding) something in the remote API. I would recommend re-reviewing the API to identify that "something", in order to figure out the right approach. Otherwise, the code will quickly become unmanageable and inefficient as you continue to tweak it to handle each "new" situation.
If for some reason the API truly is returning different results without a valid reason, the best you can do is to code according to what you expect and fail gracefully when you receive something else. Start by listing the expected possibilities:
Response is a single structure containing certain keys OR
Response is an Array of structures containing certain keys
Based on the above, you can use the IsArray and IsStruct functions to determine the format of the response, and handle it accordingly. First examine the deserialized object. If it is an array, extract the structure in the first element (Note, I am assuming the array only contains a single element, as in the example. If it can contain multiple elements, you will need additional handling).
<cfset data = deserializeJson(originalJSON)>
....
<!--- Extract structure from first element of array --->
<cfif IsArray(data) && arrayLen(data)>
<cfset data = data[1]>
</cfif>
Next verify you are now working with a structure, containing the expected key(s). If so, go ahead with your usual processing. Otherwise, something unexpected happened and the code should perform the appropriate error handling.
<!--- Verify object is a structure and contains expected key(s) --->
<cfif IsStruct(data) && structKeyExists(data, "loginHosts")>
... process data as usual
<cfelse>
... data is not in expected format, do error handling here
</cfif>
The above is a very quick and dirty example, but should demonstrate the basic idea. As long as you are certain you are using the API correctly, all you can do is code for the expected and fail gracefully when something different happens.

Resources