2016-04-08 3 views
5

Ma fonction appelle l'API SendGrid. Il renvoie une structure Array +. J'écris une fonction pour retourner un ensemble de données CFQuery.Coldfusion: boucle imbriquée sur l'appel api Array & Struct

Objectif Je souhaite transmettre un objet de données désérialisé à ma fonction et obtenir un jeu de données de requête.

Voici mon code de travail et la sortie:

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

CFdump on call

Mon code:

<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> 

Résultat:

Result

Quand j'ajoute cette ligne dans ma fonction

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

Une erreur se produit:

Type d'élément n'est pas défini dans une structure de référence CFML dans le cadre d'une expression .
L'erreur sur la ligne 71.

** complet 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> 

ERRORSg3Sg4sg5sg1err

+0

Ce qui n'est pas montré ici, c'est la fonction 'arrayit' que vous appelez. Je soupçonne que votre erreur est dans cette fonction. – beloitdavisja

+0

Merci juste édité ... le code était là mais il ne s'affichait peut-être pas à cause du formatage .. –

Répondre

1

Je viens de le faire! :) Je voulais juste partager mon projet avec vous les gars espèrent aussi qu'il aidera quelqu'un d'autre aussi ...

Demande si vous les gars trouvez quelque chose que vous pensez que je peux améliorer s'il vous plaît partager.

Spécial Merci pour la réponse sur mon post. @Beginner & @Leigh

appel API JSON Retour: 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! ....

3

Votre UDF arrayit accepte un argument de type array mais lorsque cette condition est vraie, un struct est passé, l'erreur se produit. dire,

<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> 

Ainsi, il devrait être:

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

Mais, sera différent de celui que vous avez ajouté l'erreur pour ce cas.

De plus,

  • StructInsert() prend un argument optionnel allowoverwrite qui est par défaut false et selon docs:

si la clé existe et AllowOverwrite = "Faux", ColdFusion lancers francs une exception .

+0

salut vous avez raison, c'était typeo mais je reçois encore erreur même après avoir ajouté l'argument d'écriture. cette erreur de temps changement de bit *** L'élément à la position 2 de la dimension 1, de la variable de tableau " ARR, " ne peut être trouvé.
L'erreur s'est produite sur la ligne 48. *** ligne 48 '' –

+0

@knowledgeSeeker Mieux ajouter cette erreur à votre question et supprimer les fautes de frappe. – Beginner

+0

Désolé pour cela juste mis à jour le code complet et les écrans de débogage merci ... –