• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

cffunction array parameter

Engaged ,
May 22, 2014 May 22, 2014

Copy link to clipboard

Copied

I have following code to get an array from jQuery to pass MS SQL Server stored procedure to update my tables.

Is it the right way to access array from passing jQuery function?

Your help and information is great appreciated,

Regards,

Iccsi,

<cffunction name="MyFunction" access="remote">

  <cfargument name="MyData" type="any" required="true">

<cfif isJSON(arguments.MyData)>

        <cfset arguments.MyData = deserializeJSON(arguments.MyData)>

    </cfif>

    <cfstoredproc procedure = "MySP">

   <cfprocparam value = "#arguments.MyData[1]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[2]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[3]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[4]#" CFSQLTYPE = "cf_sql_varchar">

   <cfprocparam value = "#arguments.MyData[5]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[6]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[7]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[8]#" CFSQLTYPE = "CF_SQL_LONGVARCHAR">

   <cfprocparam value = "#arguments.MyData[9]#" CFSQLTYPE = "CF_SQL_LONGVARCHAR">

   <cfprocparam value = "#arguments.MyData[10]#" CFSQLTYPE = "cf_sql_date">

   <cfprocparam value = "#arguments.MyData[11]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[12]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[13]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[14]#" CFSQLTYPE = "cf_sql_varchar">

   <cfprocparam value = "#arguments.MyData[15]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[16]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[17]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[18]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[19]#" CFSQLTYPE = "cf_sql_numeric">

   <cfprocparam value = "#arguments.MyData[20]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[21]#" CFSQLTYPE = "cf_sql_date">

   <cfprocparam value = "#arguments.MyData[22]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[23]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#arguments.MyData[24]#" CFSQLTYPE = "cf_sql_integer">

   

</cfstoredproc>

</cffunction>

Views

1.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , May 23, 2014 May 23, 2014

Further remarks.

(1) The suggestion "MyServer.cfc?method=MyFunction" implies type: "GET".

(2) The JQuery line

data: { argumentCollection: JSON.stringify([$("#txtField1").val(), etc])} implies

<cffunction name="MyFunction" access="remote">

<cfargument name="argumentCollection" type="any" required="true">

</cffunction>

Votes

Translate

Translate
Guide ,
May 22, 2014 May 22, 2014

Copy link to clipboard

Copied

I could very well be wrong, but I don't believe it's recommended to replace values of variables in the arguments scope.  Instead of

<cfset arguments.MyData = deserializeJSON(arguments.MyData)>

I would maybe do

<cfset local.MyData = deserializeJSON(arguments.MyData)>

Then use local.MyData instead of arguments.MyData in all of your subsequent code.  That way the original argument is preserved (in case you find the need to use it down the road).

I'm also a bit uncomfortable assuming that the array coming from your AJAX request is valid and all values are in the correct order.  It very well might be that your front-end code assembles that array perfectly, but I wouldn't count on that always being the case.  You need to do some validation to make sure that each value in the array is present and not null (or empty), and is the correct type.  You might consider submitting a JSON object (key/value pairs) instead of an array, as that will be deserialized into a ColdFusion struct.  You could then refer to each value in the struct by keyname instead of array position (so the order of values in the JSON object would not matter), and validating each key/value pair might be easier than validating the array.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

One more remark, in addition to what Carl has said. The code assumes an array, so you must test for its existence beforehand.

<cffunction name="MyFunction" access="remote">

<cfargument name="MyData" type="any" required="true">

<cfset var thisData = arguments.MyData>

<cfif isJSON(arguments.MyData)>

        <cfset thisData = deserializeJSON(arguments.MyData)>

</cfif>

<cfif isArray(thisData)>

<cfstoredproc procedure = "MySP">

   <cfprocparam value = "#thisData[1]#" CFSQLTYPE = "cf_sql_integer">

   <cfprocparam value = "#thisData[2]#" CFSQLTYPE = "cf_sql_integer">

<!--- etc.--->

<cfelse>

<!--- What to do if there is no array--->

</cfif>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Thanks for the information and help,

I got WDDX packet parse error at line 1 column 1 content is not allowed in prolog...

  when I send the array to the cffunction.

I use CFoutput, but it does not show the data I sent.

It seems that CF does not recognize the array sent from my client from jQuery.

Thanks again for helping and information,

Regards,

Iccsi,

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

It sounds like ColdFusion doesn't realize that the data being sent is JSON, and is assuming it is WDDX-wrapped XML. 

  1. Can you tell which line of your code is causing the error (the WDDX packet parse error line number is probably the line of the incoming data that causes the error, not the line in your code)? 
  2. Can you show the jQuery code that submits the data to ColdFusion (as you might be missing an argument that sets the content type)?
  3. What does the data in your AJAX request look like? (Use your browser's developer tools or a sniffer like Fiddler or Charles to examine the request content)

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Here is my jQuery code,

Thanks again,

Regards,

Iccsi,

jQuery.ajax({

url:   "MyServer.cfc",

data:       {

           method: 'MyMethod',

           argumentCollection: JSON.stringify([jQuery("#txtField1").val(),

             jQuery("#lstField2").val(),

             jQuery("#lstField3").val(),

             jQuery("#txtField4").val(),

             jQuery("#lstField5").val(),

             jQuery("#lstField6").val(),

             jQuery("#lstField6").val(),

             jQuery("#txtField7").val(),

             jQuery("#txtField8").val(),

             jQuery("#dtpField9").val(),

             jQuery("#lstField10").val(),

             jQuery("#lstField11").val(),

             jQuery("#lstField12").val(),

             jQuery("#txtField13").val(),

             jQuery("#lstField14").val(),

             jQuery("#lstField15").val(),

             jQuery("#lstField16").val(),

             jQuery("#lstField17").val(),

             jQuery("#txtField18").val(),

             jQuery("#lstField19").val(),

             jQuery("#dtpField20").val(),

             jQuery("#lstField21").val(),

             jQuery("#lstField22").val(),

             jQuery("#lstField23").val()

             ]

             )

          },

           

              type: "POST",

              success: function(data)

              {

               

                  alert(" Data update completed");

               

                 

              }

});

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Yeah, I think you need to restructure that jQuery.ajax() call (take another look at the jQuery api docs).  Take method out of the "data" and append it to the URL as "MyServer.cfc?method=MyMethod". 

Also, what, exactly does the JSON data look like coming out of the browser (again - use your developer tools or a sniffer and paste the result in your reply)? 

You might have a nested object structure being built.  You're creating an object with an "argumentCollection" property (key), but you don't reference the argumentCollection key in your ColdFusion CFC.  I think you should be able to remove that and just do:

data:   JSON.stringify([jQuery("#txtField1").val(),

             jQuery("#lstField2").val(),

             jQuery("#lstField3").val(),

             jQuery("#txtField4").val(),

             jQuery("#lstField5").val(),

             jQuery("#lstField6").val(),

             jQuery("#lstField6").val(),

             jQuery("#txtField7").val(),

             jQuery("#txtField8").val(),

             jQuery("#dtpField9").val(),

             jQuery("#lstField10").val(),

             jQuery("#lstField11").val(),

             jQuery("#lstField12").val(),

             jQuery("#txtField13").val(),

             jQuery("#lstField14").val(),

             jQuery("#lstField15").val(),

             jQuery("#lstField16").val(),

             jQuery("#lstField17").val(),

             jQuery("#txtField18").val(),

             jQuery("#lstField19").val(),

             jQuery("#dtpField20").val(),

             jQuery("#lstField21").val(),

             jQuery("#lstField22").val(),

             jQuery("#lstField23").val()

             ]

             ),

I'm assuming all these fields are part of an HTML form, so rather than manually building your array, why not use the jQuery .serializeArray() function to do the work for you?  This will build an array of JavaScript objects (key/value pairs), that will deserialize on the ColdFusion side to an array of structs.  Then you'd simply have:

data: jQuery( "#myForm" ).serializeArray(),

Then modify your CFC to work with this new arrangement of JSON data.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Also, is "$" reserved in your JavaScript code for something other than jQuery?  If not, use the "$" shorthand instead of "jQuery" on all of your selectors.  It'll save you a ton of keystrokes.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Something apparently went wrong even before you called the function. Take a step back to where you called myFunction(someArg). What is the nature of the argument that you used? One way to find out is simply to return the argument, like this:

<cffunction name="MyFunction" access="remote">

<cfargument name="MyData" type="any" required="true">

<cfreturn serializeJSON(arguments.MyData)>

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Further remarks.

(1) The suggestion "MyServer.cfc?method=MyFunction" implies type: "GET".

(2) The JQuery line

data: { argumentCollection: JSON.stringify([$("#txtField1").val(), etc])} implies

<cffunction name="MyFunction" access="remote">

<cfargument name="argumentCollection" type="any" required="true">

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 23, 2014 May 23, 2014

Copy link to clipboard

Copied

Yup, good points @BKBK.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
May 26, 2014 May 26, 2014

Copy link to clipboard

Copied

LATEST

Thanks a million for the information and help,

Regards,

Iccsi,

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation