AJAX & Standard Requests - Same Handler?

Hello Guys,

I've been doing quite a bit of work this past week with AJAX requests - and I'm making solid progress.

One of the challenges I'm having at the moment is the varying behaviour of my event handlers, based on whether it's a standard form post of an ajax request that's inbound.

For instance, say I have a save() method in my handler;

If it's a standard form post, I want to direct the user to another page based on error / success.

If it's an AJAX request however I want to send back a JSON packet with some details in, and NOT redirect them.

The way I've been doing this until now is by putting a 'format' flag in the request - like so:

      // Render the response based on the format of the request.
      if(rc.format == "json") {
        // This is a JSON / XML request, render the data.
        event.renderData(type=rc.format, data=rc);
      } else {
        setNextEvent("services.add");
      };

However, I find this a little verbose, and some handlers will have 2 or 3 different if/else blocks. at varying points to handle the different outcomes of the controller method.

Has anyone got any suggestions on this could be handled better?

Thanks.

Robert

A quick an easy way to handle that could be to simply add a preHandler
to determine the layout. There's an example on the old (soon to be
deprecated) wiki:

http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbEventHandlersGuide#EventHandlerImplicitEvents:preHandlerpostHandler

There are also the preViewRender and preLayout interceptions points.

robert,

i ran into this same design issue.

my solution was to write a function in a helper UDF for all my
handlers.

public any function _setNextEvent(string event){
    var requestContext =
getController().getRequestService().getContext();

    if(!requestContext.isProxyRequest()){
      setNextEvent(argumentCollection=arguments);
    }
  }

since i use the proxy for ajax requests, i test against
ixProxyRequest(). if your ajax is pointing directly at your events,
the requestContext has isAjax().

Aaron

Robert,

Personally I would separate the logic into a model, and then have two controllers one for each type. So in your example you could create an API RESTful or even just an Ajax API, that would be a wrapper to the main model logic.

The same would then also apply to the handler, which would become a wrapper for the same model logic.

The only difference would be that they both have different ways to return the data, and you could code them with the correct way to handle errors if and when they do pop up.

I prefer this method, because it separates the two and clearly defines the entry point.

Once you start creating a controller / handler with logic with if conditions, you are then adding complexity to something that really doesn’t require that type of complexity, but more importantly you will end up having to write complex unit tests for these handlers.

My motto is keep the controller / Handler as simple as it can be.

even if you wrap your applications model with something like restful
services or the proxy, any event you consume with a setNextEvent()
will produce unfavorable results.

the reason why is that setNextEvent ends with a <cflocation />. there
is no way to intercept setNextEvent's behavior to stop it.

I was talking about instead of.

i understand that.

i like the idea of writing one event and having that event be consumed
as normal or via the proxy instead having to fork the logic in a
separate method somewhere else.

one event; many entry points.