3

I have an api call that gets survey results from a 3rd party. I then DeserializeJSON the result and it looks like this (n.b structs within the questionResults have been minimised for space):

enter image description here

I then loop through the first level and can pull the first level values (eg deviceName id etc) however I cant seem to find a way of getting the questionResults data. As specially I need the questionText and resultValue variables. (within the questionResults there are always 11 array results, each with identical setup structs)

Currently I'm using the following code:

<cfhttp url="#myurl#" method="POST" result="myresult">
  <cfhttpparam type="URL" name="apiKey" value="#apiKey#">
  <cfhttpparam type="URL" name="SurveyId" value="#SurveyId#">       
</cfhttp>

<cfset recordData=DeserializeJSON(#myresult.filecontent#)>

<cfdump var="#recordData#">

<cfloop from="1" to="#ArrayLen(recordData)#" index="i">
   <cfoutput>
     <strong>Record ID:</strong> #recordData[i].id#<br>

      <cfloop from="1" to="#ArrayLen(recordData[i])#" index="j">
            #recordData[i][j]#<br>
      </cfloop>
   </cfoutput>
   <hr> 
 </cfloop>

But get the error "Struct cannot be used as an array"

Any advice on how to get the data that I'm after?

2
  • This line <cfloop from="1" to="#ArrayLen(recordData[i])#" index="j"> - recordData[i]is a struct. You can not use the for loop. recordData[i].questionResult` is an array you can loop. Commented Apr 27, 2018 at 11:48
  • What data points do you need out of your JSON string? And can you post an example of the returned JSON? Commented Apr 27, 2018 at 13:50

3 Answers 3

2

I think that when you are looping through structures or arrays or pretty much anything, script syntax is much easier to visualize.

NOTE: I can't access my Gists to save it for TryCF right now.

First, I setup my "JSON" value:

<cfscript>

myresult.filecontent = '[
    {
        deviceIdentifier: "asdf" ,
        deviceName : "localiPad1" ,
        id : "23155736" ,
        otherStuff : "adsfasdfasd" ,
        questionResults : [
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "G8N9" ,
                questionText : "Select User" ,
                questionType : "Text" ,
                resultValue : "Beatriz Pinho"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "2" ,
                questionText : "Question2" ,
                questionType : "Text" ,
                resultValue : "Answer2"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "3" ,
                questionText : "Question3" ,
                questionType : "Text" ,
                resultValue : "Answer3"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "4" ,
                questionText : "Question4" ,
                questionType : "Text" ,
                resultValue : "Answer4"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "5" ,
                questionText : "Question5" ,
                questionType : "Text" ,
                resultValue : "Answer5"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "6" ,
                questionText : "Question6" ,
                questionType : "Text" ,
                resultValue : "Answer6"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "7" ,
                questionText : "Question7" ,
                questionType : "Text" ,
                resultValue : "Answer7"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "8" ,
                questionText : "Question8" ,
                questionType : "Text" ,
                resultValue : "Answer8"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "9" ,
                questionText : "Question9" ,
                questionType : "Text" ,
                resultValue : "Answer9"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "10" ,
                questionText : "Question10" ,
                questionType : "Text" ,
                resultValue : "Answer10"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "11" ,
                questionText : "Question11" ,
                questionType : "Text" ,
                resultValue : "Answer11"
            } 
        ] ,
        moreOtherStuff : "asdfasdfasdfasd"
    } ,
    {
        deviceIdentifier: "fdsa" ,
        deviceName : "localiPad2" ,
        id : "2" ,
        otherStuff : "adsfasdfasd" ,
        questionResults : [
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "G8N9" ,
                questionText : "Select User" ,
                questionType : "Text" ,
                resultValue : "Silent Bob"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "2" ,
                questionText : "Question2" ,
                questionType : "Text" ,
                resultValue : "Answer2"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "3" ,
                questionText : "Question3" ,
                questionType : "Text" ,
                resultValue : "Answer3"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "4" ,
                questionText : "Question4" ,
                questionType : "Text" ,
                resultValue : "Answer4"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "5" ,
                questionText : "Question5" ,
                questionType : "Text" ,
                resultValue : "Answer5"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "6" ,
                questionText : "Question6" ,
                questionType : "Text" ,
                resultValue : "Answer6"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "7" ,
                questionText : "Question7" ,
                questionType : "Text" ,
                resultValue : "Answer7"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "8" ,
                questionText : "Question8" ,
                questionType : "Text" ,
                resultValue : "Answer8"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "9" ,
                questionText : "Question9" ,
                questionType : "Text" ,
                resultValue : "Answer9"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "10" ,
                questionText : "Question10" ,
                questionType : "Text" ,
                resultValue : "Answer10"
            } ,
            {
                answerDate : "2018-04-26T09:25:55:55.0000000" ,
                questionIdentifier : "11" ,
                questionText : "Question11" ,
                questionType : "Text" ,
                resultValue : "Answer11"
            } 
        ] ,
        moreOtherStuff : "asdfasdfasdfasd"
    }
]' ;

I created a JSON variable that simulates what you get returned from your http request. I'll then deserialize the JSON from that.

recordData = deserializeJSON(myresult.filecontent) ;

Which gives me the nice array with structs and other arrays in it.

This is the part that I find much easier in script.

for ( var i IN recordData ) {  // loop through the outer array

    writeOutput("<strong>Record ID:</strong>" & i.id & "<br>") ;

    for ( var j IN i.questionResults ) { // loop through each questionResults
        writeOutput(
            j.questionIdentifier & " - " & 
            j.questionText
            &  " >> " & 
            j.resultValue 
            & " ------- " &
            j.answerDate
            & "<br>"
        ) ;
    }
}

And close my script.

</cfscript>

If I could get my TryCF.com code to display correctly, you'd see this returns:

Record ID:23155736
G8N9 - Select User >> Beatriz Pinho ------- 2018-04-26T09:25:55:55.0000000
2 - Question2 >> Answer2 ------- 2018-04-26T09:25:55:55.0000000
3 - Question3 >> Answer3 ------- 2018-04-26T09:25:55:55.0000000
4 - Question4 >> Answer4 ------- 2018-04-26T09:25:55:55.0000000
5 - Question5 >> Answer5 ------- 2018-04-26T09:25:55:55.0000000
6 - Question6 >> Answer6 ------- 2018-04-26T09:25:55:55.0000000
7 - Question7 >> Answer7 ------- 2018-04-26T09:25:55:55.0000000
8 - Question8 >> Answer8 ------- 2018-04-26T09:25:55:55.0000000
9 - Question9 >> Answer9 ------- 2018-04-26T09:25:55:55.0000000
10 - Question10 >> Answer10 ------- 2018-04-26T09:25:55:55.0000000
11 - Question11 >> Answer11 ------- 2018-04-26T09:25:55:55.0000000
Record ID:2
G8N9 - Select User >> Silent Bob ------- 2018-04-26T09:25:55:55.0000000
2 - Question2 >> Answer2 ------- 2018-04-26T09:25:55:55.0000000
3 - Question3 >> Answer3 ------- 2018-04-26T09:25:55:55.0000000
4 - Question4 >> Answer4 ------- 2018-04-26T09:25:55:55.0000000
5 - Question5 >> Answer5 ------- 2018-04-26T09:25:55:55.0000000
6 - Question6 >> Answer6 ------- 2018-04-26T09:25:55:55.0000000
7 - Question7 >> Answer7 ------- 2018-04-26T09:25:55:55.0000000
8 - Question8 >> Answer8 ------- 2018-04-26T09:25:55:55.0000000
9 - Question9 >> Answer9 ------- 2018-04-26T09:25:55:55.0000000
10 - Question10 >> Answer10 ------- 2018-04-26T09:25:55:55.0000000
11 - Question11 >> Answer11 ------- 2018-04-26T09:25:55:55.0000000

NOTE: I'm running this in Lucee. ACF doesn't like my JSON parsing, and I haven't dug through it to find which character it doesn't like. It still works though. :-)

Sign up to request clarification or add additional context in comments.

Comments

1

You have an array of structures and one of the structure elements is another array of structures named questionResults. I suggest this approach.

<cfloop array="#recordData#" index="ThisStructure">
do the easy stuff 
<cfif StructkeyExists(ThisStructure, "questionResults">
loop through that array and process it
closing tags

Comments

1

From your sample code it looks like you are referencing the same initial array in your second loop. That looks wrong to me. Try this instead.

<cfloop from="1" to="#ArrayLen(recordData)#" index="i">
    <cfoutput>
        <strong>Record ID:</strong> #recordData[i].id#<br>

        <cfloop from="1" to="#ArrayLen(recordData[i].questionResults)#" index="j">
            <cfdump var="#recordData[i].questionResults[j]#">
        </cfloop>
    </cfoutput>
    <hr> 
</cfloop>

I changed this <cfloop from="1" to="#ArrayLen(recordData[i])#" index="j"> to this <cfloop from="1" to="#ArrayLen(recordData[i].questionResults)#" index="j">

Update

In response to your comment, I updated my code example by changing this code #recordData[i][j]#<br> to this code <cfdump var="#recordData[i].questionResults[j]#"> as you cannot just simply output complex values as the error you reported stated.

You should be able to reference the questionText data (and other elements) like this #recordData[i].questionResults[j].questionText#.

3 Comments

Thanks for your reply, I'm now getting this error "Complex object types cannot be converted to simple values. The expression has requested a variable or an intermediate expression result as a simple value. However, the result cannot be converted to a simple value. Simple values are strings, numbers, boolean values, and date/time values. Queries, arrays, and COM objects are examples of complex values."
That's because of how you are referencing the second array. Sorry I didn't catch that in my original answer. I have updated the answer to dump that value instead.
@SamAllen - Unless there's a reason you must use for/to loops, try using <cfloop array="..." ...>. With "array" loops the index is the array element, so less moving pieces. Easier to work with imo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.