0

I have a page that is making an $.ajax call to a handler method in Coldbox. I've done this many times, but in this current project, more than once, if I dump the rc scope at the start of the handler, there's nothing in it other than my usual stuff I add elsewhere on each request.

What's even more weird is that if I don't interrupt the flow of execution it will go from the handler into the model and through the query and back out and return a SUCCESS, even though none of the required values are there. If I dump the arguments scope in the model, nothing is there either. This sounds like either a coldbox bug or a misconfiguration or something, but at this point I'll hope it's something I'm doing wrong.

So, first up, here's the AJAX call:

function deleteAgendaItem(agendaid, eventid) {

var data = {},
    url = "<cfoutput>#event.buildLink('agenda.delete')#</cfoutput>";

data.eventid = eventid;
data.agendaid = agendaid;

var xhr = $.ajax({type: "post", data: data, url: url, async: false, dataType : "json", contentType: "application/json; charset=utf-8"});

return JSON.parse(xhr.responseText);

}

I've dumped my data structure to ensure the values are in there.

Here's the handler in coldbox:

<cffunction name="delete">
    <cfargument name="event">
    <cfargument name="rc">
    <cfargument name="prc">

    <cfscript>
    param rc.agendaid = 0;
    param rc.eventid = 0;
    var modelObj = getModel('agenda');
    var data = modelObj.delete(agendaid=rc.agendaid, eventid=rc.eventid, clientid=rc.userInfo.currentClientID);

    event.renderData(format="json", data=SerializeJSON(data));
    </cfscript>

</cffunction>

This is where stuff gets weird. If I dump rc, there's nothing in it other than my rc.userInfo.* stuff which is added in the prehandler (it's the contents of the user's cookie).

For completeness, here's the model:

<cffunction name="delete" output="false" access="public" returntype="struct">
    <cfargument name="agendaid" type="numeric" required="yes">
    <cfargument name="eventid" type="numeric" required="yes">
    <cfargument name="clientid" type="numeric" required="yes">

    <cfset var ret = StructNew()>
    <cfset ret.success = true>

    <cfquery datasource="#variables.dsn#">
        update agenda
        set active = 0
        where agendaid = <cfqueryparam value="#arguments.agendaid#" cfsqltype="cf_sql_integer">
        and eventid = <cfqueryparam value="#arguments.eventid#" cfsqltype="cf_sql_integer">
        and clientid = <cfqueryparam value="#arguments.clientid#" cfsqltype="cf_sql_integer">
    </cfquery>

    <cfreturn ret>

</cffunction>

Like I said earlier, if I let everything run, it will pass on through the model and return ret, which is success=true. No errors thrown. VERY weird. And if I dump arguments, there's nothing in it.

I've dumped both event.getHTTPContent() and getHttpRequestData() and they too are empty when it comes to the data I'm sending over.

I'm running on CF2016 on a Mac, but I've run the same code on a Windows server running Lucee and the same issue occurs. My Coldbox verion is v4.3.0.

Another thing worth mentioning... I've had this same problem with other calls in this project, with one difference... while I can't see any of the values being passed in (they too are blank), if I let it run through the model, IT WORKS FINE. I still can't dump them in the model either. That is beyond bizarre...note that while I do param the values going into the model, the fact that when I dump the arguments scope in the model and nothing appears is weird.

21 years doing ColdFusion and eight years doing Coldbox and this is the weirdest thing I've seen...

So... maybe another set of eyes will help. Am I doing something wrong? I must be. Thanks. :)

RobG
  • 576
  • 2
  • 9
  • 21
  • 2
    What does the F12 tool of your browser show? What data is POSTed to the server? – Bernhard Döbler Sep 22 '17 at 17:14
  • This issue has gotten VERY deep; it's beyond even the scope of Stack Overflow. If/when I find a solution, I'll post it. – RobG Sep 22 '17 at 21:34
  • Echo what @BernhardDöbler asked: What shows as the `POST`ed data? I ask because a coworker was having this exact issue. Basically, he had `data.eventid = $('#eventid').val()`, but nothing was posted. Discovered in his HTML that the input has `name="eventid"`, not `id="eventid"`, so the `data` object was undefined and nothing was submitted. – Adrian J. Moreno Sep 25 '17 at 21:32

2 Answers2

1

Coldbox 4.x will not de-serialize a JSON payload body in the request, by default - which your $.ajax call is sending. This changes in the upcoming 5.0 release. In the meantime, though, you will need to deserialize the inbound JSON payload - preferrably using a preHandler or aroundHandler method.

if( isJSON( event.getHTTPContent() ) ){
    structAppend( rc, event.getHTTPContent( json=true ), true );
}

Alternately, you can either change your content type of the ajax request to use multipart/form-data and those values will populate the request collection, as you would expect or develop off the BE release of Coldbox 5 ( CommandBox install box install coldbox@be )

JClausen
  • 321
  • 2
  • 2
1

With (at least) Coldbox 5.2, you must do two things:

  1. Add a Coldbox config setting of jsonPayloadToRC=true
  2. Ensure that you send the header: Content-Type=application/json

While digging in core Coldbox code for isJSON(), I found that setting. The CommandBox setup for a new site doesn't add the setting.

Once I did both things above, I was able to change all my Postman setups to application/json and "raw" for the content type and my RC dumps looked just like they did before. Bear in mind, if you've forgotten to prefix a variable with "rc.", it would've worked in the non-JSON mode, because the old school method will have your values in the URL/FORM, too. With this method, you don't get that. (You should be scoping your variables, anyway.)

Will Belden
  • 630
  • 4
  • 11