10

I have a ColdFusion CFC function like this:

<cffunction access="remote" name="getResults"
    returntype="struct"
    returnformat="JSON"
    output="no">

    <cfargument name="q" required="true" type="array" />

...
</cffunction>

How do I call this function from jQuery? Neither form of array encoding by jQuery will get ColdFusion to see the value as array.

If you pass "q=a&q=b" (like with jQuery.ajaxSettings.traditional = true), the function will get the string "a,b", not an array. While splitting on comma may seem like a possibility, it will not work if one of the "q" values contains a comma. Also, ideally, the function on the server-side should not have to be aware of the problems of how to serialize the data over the wire, and should continue to take in an array.

If you pass "q[]=a&q[]=b" (the jQuery default), it will not map over to the "q" parameter. If you try to change the name of the "q" parameter to "q[]", the CFC will error out due to an invalid parameter name.

3 Answers 3

8

First thing to know is jQuery Ajax requests do not encode arrays so have you to use something else to encode the data (this is where jquery.JSON.js comes from referenced below). So with a the JSON encoded found there, I then figured out the correct syntax by working with cfajaxproxy and studying the URL it generates in Firebug:

http://localhost/remote.cfc?method=getResults&argumentCollection=%7B%22q%22%3A%5B1%2C2%5D%7D

Yes the "argumentcollection" approach is correct, and the variable "q" with a reference to an array is in there.

I used the following code as a test bed:

remote.cfc

<cfcomponent output="false">
    <cffunction access="remote" name="getResults"
        returntype="struct"
        returnformat="JSON"
        output="no">

        <cfargument name="q" required="true" type="array" />

        <cfreturn {a=1,b=2}>
    </cffunction>
</cfcomponent>

remote.cfm to see how cfajaxproxy generates its url

<cfajaxproxy cfc="Remote" jsclassname="Remote">
<cfoutput>
<script language="javascript" type="text/javascript">
var oRemote = new Remote();
alert(oRemote.getResults([1,2]));
</script>
</cfoutput>

remote.html doing it with jQuery

<script language="javascript" src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
<script language="javascript" src="jquery.JSON.js"></script>
<script language="javascript" type="text/javascript">
var argumentCollection = { q: [1,2] };
$.ajax({
    url:        'remote.cfc',
    data:       {
        method: 'getResults',
        argumentCollection: $.JSON.encode(argumentCollection)
    },
    success:    function(response) {
        alert(response);
    },
    dataType:   'json'
});

</script>
2
  • Well, I'd say that jQuery does encode arrays, just not in a way that ColdFusion can accept. By default in jQuery 1.4.3, arrays are encoded in a fashion compatible with PHP and Ruby on Rails, by providing multiple parameters, with a parameter name that adds "[]" to the variable name. Using the "traditional" setting, it encodes them the same way an HTML form does for multiple checkboxes, just sending multiple of the parameter. Your approach for figuring this out matched mine. Thanks for the detailed sample code!
    – jrduncans
    Oct 23, 2010 at 1:44
  • I'm having similar issues today posting from Angular 4 to CF10. the argumentCollection work-around still works. Sending a JSON array as a form argument does not. It is worth noting that changing the CFC Argument type from array to any will allow the CFC code to process the argument as an array with the argumentCollection work around. May 26, 2017 at 4:01
6

Investigating this problem, I found the following blog post: http://www.coldfusionjedi.com/index.cfm/2010/3/23/Using-jQuery-to-post-an-array-to-a-ColdFusion-Component - This suggested encoding the array as a JSON string, and then deserializing it inside the CFC method, with the unfortunate impact of requiring the CFC function to have to change to deal with JSON.

So I investigated further, and here's the best solution I have found so far.

By looking at the HTTP calls made when using cfajaxproxy, I discovered that you can send a single argumentCollection parameter as a JSON string to call the remote CFC method.

So the client side call looks something like this (using jquery-json plugin to do the serialization):

var params = {q: ['a', '1,2,3']};

$.getJSON('My.cfc?method=getResults', {argumentCollection: $.toJSON(params)}, function(data) {
// handle data
});
1
  • psst... I think you dropped a ] somewhere. Oct 22, 2010 at 17:27
-1

How about checking your values for commas and escaping them before passing to Coldfusion, then use ListToArray to convert and (if necessary) re-encode the commas?

1
  • Ideally the CFC function shouldn't have to change, so that it can be called on the server-side in a normal fashion. I've updated the question to clarify that.
    – jrduncans
    Oct 22, 2010 at 17:25

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.