Coldfusion: nested loop on api call Array & Struct

My function calls the SendGrid API. It returns an Array + structure. I am writing a function to return a CFQuery dataset.

Purpose I want to pass a deserialized data object to my function and get a query data set.

Here is my working code and output:

<cfparam name="variables.ddata" default="#structnew()#"> <!--- API Call Code here ---> <cfset arr = DESerializeJSON(returnStruct.Filecontent) /> <cfdump var="#arr#"> 

CFdump on call

My code is:

  <cfset arrayit(arrobj= arr) > <cfdump var="#variables.ddata#" > <cffunction name="arrayit" access="public" returntype="void"> <cfargument name="arrobj" type="array" required="yes"> <cfset var arr=arguments.arrobj /> <cfloop from="1" to = "#arrayLen(arr)#" index="i"> <cfif isValid("string", arr[i])> <cfset StructInsert(variables.ddata, i, arr[i]) /> </cfif> <cfif isstruct(arr[i])> <cfset structit(structobj = arr[i]) /> </cfif> </cfloop> </cffunction> <cffunction name="structit" access="public" returntype="void" output="yes"> <cfargument name="structobj" type="any" required="yes"> <cfset stru = arguments.structobj /> <cfloop collection="#stru#" item="S"> <cfif isValid("string", stru[S])> <cfset StructInsert( variables.ddata, S, stru[S]) /> </cfif> <cfif isarray(stru[S])> <cfset arrayit(arrobj = stru[S]) > </cfif> </cfloop> </cffunction> 

Result:

Result

When I add this line to my function

 <cfif isstruct(stru[S])> <cfset variables.ddata = arrayit(arrobj = stru[S]) /> </cfif> 

An error has occurred:

The element type is undefined in the CFML structure referenced as part of the expression.
An error occurred on line 71.

** Full code **

  <cfsavecontent variable="returnStruct.Filecontent"> [{"date":"2016-04-05","stats":[{"type":"category","name":"5","metrics":{"blocks":1,"bounce_drops":0,"bounces":9,"clicks":4,"deferred":1,"delivered":1,"invalid_emails":8,"opens":4,"processed":1,"requests":1,"spam_report_drops":0,"spam_reports":1,"unique_clicks":3,"unique_opens":3,"unsubscribe_drops":0,"unsubscribes":9}}]}] </cfsavecontent> <cfset arr = DESerializeJSON(returnStruct.Filecontent) /> 

 <cfloop from="1" to="#arrayLen(arr)#" index="i"> <cfif isValid("string", arr[i])> <cfset StructInsert(variables.ddata, i, arr[i],true ) /> </cfif> <cfif isstruct(arr[i])> <cfsavecontent variable="rr"> <cfdump var="#arr[i]#" label="Line 48 ERROR" > </cfsavecontent> <cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 48") /> <cfset structit(structobj = arr[i]) /> </cfif> <cfif isarray(arr[i])> <cfsavecontent variable="rr"> <cfdump var="#arr[i]#" label="Line 54 ERROR" > </cfsavecontent> <cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 54") /> <cfset arrayit(arrobj = arr[i]) > </cfif> </cfloop> </cffunction> <cffunction name = "structit" access="public" returntype="void" output="yes"> <cfargument name = "structobj" type="any" required="yes"> <cfset stru = arguments.structobj /> <cfloop collection="#stru#" item="S"> <cfif isValid("string", stru[S])> <cfset StructInsert( variables.ddata, S, stru[S],true) /> </cfif> <cfif isarray(stru[S])> <cfsavecontent variable="rr"> <cfdump var="#stru[S]#" label="Line 86 ERROR" > </cfsavecontent> <cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 87") /> <cfset arrayit(arrobj = stru[S]) > </cfif> <cfif isstruct(stru[S])> <cfsavecontent variable="rr"> <cfdump var="#stru[S]#" label="Line 97 ERROR" > </cfsavecontent> <cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 97") /> <cfset structit(structobj = stru[S]) /> </cfif> </cfloop> </cffunction> 

ERROR Sg3 Sg4 sg5 sg1 err

+5
source share
2 answers

I just did it! :) I just wanted to share my project with you, the guys also hope that this will help another ...

Request, if you guys find anything that you think I can improve, please share.

Special thanks for responding to my post. @Beginner and @Leigh

Call Json Return API: 1

  <cfsavecontent variable="returnStruct.Filecontent"> [{"date":"2016-04-05","stats":[{"type":"category","name":"5","metrics":{"blocks":1,"bounce_drops":0,"bounces":9,"clicks":4,"deferred":1,"delivered":1,"invalid_emails":8,"opens":4,"processed":1,"requests":1,"spam_report_drops":0,"spam_reports":1,"unique_clicks":3,"unique_opens":3,"unsubscribe_drops":0,"unsubscribes":9}}]}] </cfsavecontent> <cfset arr = DESerializeJSON(returnStruct.Filecontent) /> 

CFC: 2

  <cfcomponent> <cfparam name="variables.qryclsvar" default="" type="any"/> <cfparam name="variables.qryclsvarfg" default="true" type="any"/> <cffunction name="APItoquery" access="public" returntype="any"> <cfargument name = "APIobj" type="any" required="yes"> <cfset var vAPIobj = arguments.APIobj /> <cfset var APIDATA = structnew() /> <cfset var APIDATAqr = "" /> <cftry> <cfloop from="1" to="#arrayLen(vAPIobj)#" index="jj"> <cfif isarray(vAPIobj[jj])> <cfset APIDATA = arrayit(structobj = vAPIobj[jj] ,datastruct = APIDATA) /> </cfif> <cfif isstruct(vAPIobj[jj])> <cfset APIDATA = structit(structobj = vAPIobj[jj],datastruct = APIDATA) /> </cfif> <cfif NOT StructIsEmpty(APIDATA)> <!--- Add in query object ---> <cfset APIDATAqr = structtoquery(structobj= APIDATA) /> <cfelse> <cfset APIDATAqr ="NO Data Found!" /> </cfif> </cfloop> <cfcatch> <cfdump var="#cfcatch#" label="APItoquery"> </cfcatch> </cftry> <cfreturn APIDATAqr> </cffunction> <cffunction name = "arrayit" access="public" returntype="any"> <cfargument name = "arrobj" type="any" required="yes"> <cfargument name = "datastruct" type="any" required="yes" > <cfset var arr = arguments.arrobj /> <cfset var arrdata = arguments.datastruct /> <cftry> <cfloop from="1" to="#arrayLen(arr)#" index="i"> <cfif ArrayContains(arr, i) > <cfset StructInsert(arrdata, i, arr[i],true ) /> </cfif> <cfif isarray(arr[i])> <cfset arrdata = arrayit(arrobj = arr[i] ,datastruct = arrdata) > </cfif> <cfif isstruct(arr[i]) > <cfset stdata = structit(structobj = arr[i],datastruct = arrdata) /> </cfif> </cfloop> <cfcatch> <cfdump var="#cfcatch#" label="arrayit"> </cfcatch> </cftry> <cfreturn arrdata> </cffunction> <cffunction name = "structit" access="public" returntype="any" output="yes"> <cfargument name = "structobj" type="any" required="yes"> <cfargument name = "datastruct" type="any" required="yes"> <cfset var stru = arguments.structobj /> <cfset var stdata = arguments.datastruct /> <cftry> <cfloop collection="#stru#" item="S"> <cfif isarray(stru[S])> <cfset stdata = arrayit(arrobj = stru[S] ,datastruct = stdata) > <cfelseif isstruct(stru[S]) > <cfset stdata = structit(structobj = stru[S],datastruct = stdata) /> <cfelse> <cfset StructInsert( stdata, S, stru[S],true) /> </cfif> </cfloop> <cfcatch> <cfdump var="#cfcatch#" label="structit"> </cfcatch> </cftry> <cfreturn stdata> </cffunction> <cffunction name = "structtoquery" access="public" returntype="any" output="yes"> <cfargument name = "structobj" type="any" required="yes"> <cfset var vstructobj = arguments.structobj /> <cfset var cols = StructKeyList(vstructobj)> <cfset var colstyp = ""> <cftry> <cfif variables.qryclsvarfg EQ true> <cfloop from="1" to="#listlen(cols,',')#" index="L"> <cfset colstyp = ListAppend(colstyp,"VarChar",",")> </cfloop> <!--- Create a new query. ---> <cfset variables.qryclsvar = queryNew( '#cols#', '#colstyp#' )> <cfset variables.qryclsvarfg = false> </cfif> <cfset QueryAddRow(variables.qryclsvar, 1)> <cfloop collection="#vstructobj#" item="sd"> <cfset QuerySetCell(variables.qryclsvar, "#sd#", vstructobj[sd])> </cfloop> <cfcatch> <cfdump var="#cfcatch#" label="structit"> </cfcatch> </cftry> <cfreturn variables.qryclsvar> </cffunction> </cfcomponent> 

CFM: 3

 <cfset sgObj = createobject("component","cfc.mycfc") /> <cfset mystruct = sgObj.APItoquery(APIobj= arr1) > <cfdump var="#mystruct#" label="mystruct"> 

MA! ....

+1
source

Your UDF arrayit accepts an argument of type array , but when this condition is true, then a struct is passed like that, an error. i.e.,

 <cfif isStruct(stru[S])> <!--- This means stru[S] is a struct ---> <cfset variables.ddata = arrayit(arrobj = stru[S])> <!--- arrObj should be of type 'array' ---> </cfif> 

So this should be:

 <cfif isStruct(stru[S])> <cfset variables.ddata = structit(structobj = stru[S])> </cfif> 

But the error for this case will be different from what you added.

Besides,

  • StructInsert() accepts an optional allowoverwrite argument, which is false by default and as per the docs:

if the key exists and allowoverwrite = "False", ColdFusion throws an exception.

+3
source

Source: https://habr.com/ru/post/1246746/


All Articles