Skip to main content
Inspiring
February 21, 2022
Answered

StructKeyExists Question

  • February 21, 2022
  • 2 replies
  • 606 views

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

    This topic has been closed for replies.
    Correct answer BKBK

    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>

     

     

     

     

    2 replies

    BKBK
    Community Expert
    BKBKCommunity ExpertCorrect answer
    Community Expert
    February 22, 2022

    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>

     

     

     

     

    ghanna1Author
    Inspiring
    February 22, 2022

    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

    Charlie Arehart
    Community Expert
    Community Expert
    February 22, 2022

    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. 

    /Charlie (troubleshooter, carehart. org)
    ghanna1Author
    Inspiring
    February 22, 2022

    Thanks Charlie. ArrayIsDefined works perfect!

    Charlie Arehart
    Community Expert
    Community Expert
    February 22, 2022

    Great to hear, and glad to help.

    /Charlie (troubleshooter, carehart. org)