Copy link to clipboard
Copied
Hi,
I have a stuct that looks like this:
If I need to display the attributes array. This works:
<cfoutput>#shipment_response.data.rates["9"].attributes[1]#</cfoutput>
However sometimes the Array is [empty]. How can I determine if it exists? I tried:
<cfif StructKeyExists(shipment_response.data.rates["9"], "attributes[1]")>
<cfoutput>#shipment_response.data.rates["9"].attributes[1]#</cfoutput>
</cfif>
It doesn't execute the cfoutput either way (exists or empty). What am I doing wrong with StructKeyExists?
Thanks in advance for any suggestions!
Gary
Gary, use the little-known arrayisdefined, introduced in cf8.
Or there can be times when this sort of problem might be solved as well using either the elvis operator or the safe navigation operator.
Let us know if any works for you.
Hi @ghanna1 ,
What a delightful coincidence. I worked in shipping logistics for 6 years, and processing XML data similar to yours was the daily grind. 🙂
Your current approach is on the right track. A response may or may not have attributes. When it does, then the attributes array is either empty or non-empty.
With that in mind, you could extend your approach as follows:
<!--- Does 'rates["9"]' have an 'attributes' key? True or False --->
<cfset attributesArrayExists = structKeyExists(shipme
...
Copy link to clipboard
Copied
Gary, use the little-known arrayisdefined, introduced in cf8.
Or there can be times when this sort of problem might be solved as well using either the elvis operator or the safe navigation operator.
Let us know if any works for you.
Copy link to clipboard
Copied
Thanks Charlie. ArrayIsDefined works perfect!
Copy link to clipboard
Copied
Great to hear, and glad to help.
Copy link to clipboard
Copied
Hi @ghanna1 ,
What a delightful coincidence. I worked in shipping logistics for 6 years, and processing XML data similar to yours was the daily grind. 🙂
Your current approach is on the right track. A response may or may not have attributes. When it does, then the attributes array is either empty or non-empty.
With that in mind, you could extend your approach as follows:
<!--- Does 'rates["9"]' have an 'attributes' key? True or False --->
<cfset attributesArrayExists = structKeyExists(shipment_response.data.rates["9"], "attributes")>
<cfif attributesArrayExists>
<!--- Is 'attributes' array non-empty? True or False --->
<cfset attributesArrayIsNonEmpty = arrayLen(shipment_response.data.rates["9"].attributes) gt 0>
<cfif attributesArrayIsNonEmpty>
<!--- Do your stuff here --->
</cfif>
</cfif>
Or, in short:
<cfif structKeyExists(shipment_response.data.rates["9"], "attributes") and
arrayLen(shipment_response.data.rates["9"].attributes) gt 0>
<!--- Do your stuff here --->
<cfelse>
<!--- Handle exception here: "attributes" doesn't exist or is an empty array --->
</cfif>
Copy link to clipboard
Copied
Thank you! This is something I've had on the back burner for years to save our fulfilment team the task of double data entry between our portal and UPS. We've used the UPS API before but after writing all the code they dumped the particular platform we were using for a more secure method. A few days ago I stumbled upon the Shippo API which allows you to compare multiple carriers, print the label then uses webhooks to update the status and delivery. Way more functionality than UPS and easier to work with.
G