2
votes

I am receiving a JSON string back from an API call and deserializing it. However, I'm having issues trying access some of the keys within the nested structures:

Screen shot of deserialized JSON

When I do the following, I get the list of all outer keys, but I'm not sure how to proceed from there.

<cfset jsonData = deserializeJSON(httpResp.fileContent) /> 

<cfloop collection="#jsonData#" item="i">
<cfoutput>
    <br>#i#
</cfoutput> 
</cfloop>

Ultimately, I need to get to the street array data, barcode and sku, within in the items element. I've tried using dot notation, but am receiving the error:

You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.

1
What are you trying to do with the data in the struct? Are you looking for a specific key? - Shawn
"..having issues..." You need to be more specific ;-) The concept looks similar to your other question which was just a matter of accessing the keys using dot-notation. You'd use the same approach for this structure - only difference is the key paths. So what part are you struggling with? Could you provide an example, like "I need to access X, and have tried code Y, but am getting result/error Z". - SOS
And how are you creating the struct? Is this coming in from JSON or a query? - Shawn
What Ageax said. - TRose
Sure the data structure is different, but the concept of how to access keys is the same: you just need to find the right path to the keys. (Once you get used to JSON, you'll realize it's basically use X syntax for a structure or Y for an array. The rest is all lather, rinse, repeat ;-) Anyway, best to start simple. Please edit your question to include the code you tried for one of the keys (and the error message). - SOS

1 Answers

3
votes

The error just means your path is wrong, and the code is treating something as a structure that's actually just a string. While the data structure may be different than in your other thread, the concept of how to access values is the same. You just need to find the correct path to the desired keys. Keep in mind, JSON is a very simple format. It essentially consists of two object types: structures and arrays. So accessing ANY element just requires the correct series of key name(s) and/or array position(s).

Usually structure keys can be accessed with dot-notation. However, if the key names don't conform to CF's variable naming rules, you'll need to use associative array notation (or a mix of both):

     someStructure.path.to.keyname          <== dot-notation
     someStructure["path"]["to"]["keyname"] <=== associative array notation
     someStructure.path["to"].keyname      <=== mix of both

street element

Accessing this element is very straightforward. The key name is a valid variable name, so it can be accessed with dot-notation. Since it's value is an array, you'll also need to supply a position if you only want a specific element within that array:

   addresses.customer.street[1] <=== first element  
   addresses.customer.street[2] <=== second element  

barcode element

Similarly, barcode is a key within a nested structure. However, there are two differences. Some of the parent key names contain invalid characters (dashes), so you can't use dot-notation to access "barcode". Also, some of the parent keys appears to be dynamic:

   items.{dynamic_uuid}.metadata.barcode   

Since you won't know those ahead of time, the only way to access them is by looping through the parent structure (items) keys dynamically and using associative notation:

<!--- demo structure --->
<cfset props = {items : {"#createUUID()#" : {metadata : {barcode :"759855743302"}} } }>

<cfloop collection="#props.items#" item="dynamicKey">
    <cfoutput>
        barcode = #props.items[dynamicKey].metadata.barcode# 
    </cfoutput>
</cfloop>