-
Notifications
You must be signed in to change notification settings - Fork 4
When
The route object has a when method which takes either a single parameter (the when definition object), a few parameters with which it generates the when definition object, or an array of def objects.
when(def);
when(name, in, out, fn, advOpts);
when([def, def, def, ...])In the second case, name is a string, in and out are arrays (they map to params and produces respectively) and advOpts is optional but may contain any option in the full when definition object.
The when method is chainable and returns a route object.
##when definition object ##
The when definition object is the meat of any route. The following examples is an example of a when block. Each field is described in detail below.
{
name : 'a name', /* not required */
params : [], /* not required */
produces : [], /* not required */
triggerOn : [], /* not required */
takeMany: false /* not required */
fn : function(produce, input) { produce.done()}, /* required */
enter: function(input) { return input; }, /* not required */
exit: function(output) { return output; }, /* not required */
}optional
The name of the function, used for debugging and error reporting purposes. While this is optional it's highly recommended.
optional
The parameters your function requires. These will be passed to you as an object to the second parameter to your function. If you don't require any parameters you can omit this field.
optional
The parameters your function produces. If you produce a value you have not declared here, a warning will be printed to the console and the value will be ignored.
optional
fn is the workhorse of the when definition object. The function will execute when all the parameters are ready (assuming enter didn't return an undefined/null). The signature of the fn function is:
function(producer, input) {
}producer is an object with 4 methods:
-
produce(name, value)- This method allows the function to create values for other when blocks or render to use.producemay be called any number of times. -
error(code, description)- This method allows the function to notify the system of an error. Any when block that calls error immediately ends the execution of the route and an error is returned to the browser.codeis returned as the HTTP status code anddescriptionis returned as the body. -
done()- This method notifies the system that you will not produce any more values for this call (you may produce more values if you are called again). YOU MUST call this in every fn function (unless you use fromNodeCallback). If your route hangs, the first thing you should look for is a when definition object fn that does not call done. -
fromNodeCallback(produce, cbIndex, func, thisBinding, funcArgsMinusCB...)- This method wraps a node callback and produces values on your behalf. You should not call done when using this method.produceshould be an array of values to produce (one for each parameter that the callback will receive except err). If the callback returns parameters which you are not interested in you may pass null for those positions. For example if a callback returns(err, executionTime, results)and you are not interested inexecutionTimeyou would pass[null, 'queryResults']for the produce parameter.cbIndexis the callback function index. As a convenience, if the callback is the last parameter, you can setcbIndexto-1. The following example demonstrates the usage:
producer.fromNodeCallback(['fstat'], -1, fs.stat, null, './samples/from.callback.js');optional
If present, this function will be called with the input object prior to calling fn. The value returned from the enter function is passed to fn allowing enter to transform the value prior to fn being called. To prevent fn from being called return undefined from the enter function (allowing enter to be used as a filter function). The signature of this function should be:
function(input) {
}optional
If present, this function will be called after each value produced by fn. The value returned by exit will be published instead of the value produced by fn. The signature is:
function(value) {
//value.name is the "name" from produce(name, value)
//value.value is the "value" from produce(name, value)
}While exit can edit the name or value, the structure of the response object must either be null/undefined or the same as the structure of the input object.
optional
triggerOn specifies which values to monitor. If you omit triggerOn and specify takeMany, then, after the first time you're called, any change to any value in your params will cause your function to be executed again. With triggerOn you can limit what causes your function to be activated.
optional
If set to true, fn can be called each time params are available, otherwise fn will only be called the first time params are available.
A when block is executed when all the values it has declared in it's params array are available. Initially the system looks for when blocks that can execute based on the URL variables, request headers, and/or any injected parameters. It runs these blocks immediately (in no particular order). Each time a block produces a value the system checks to see if any other when blocks are able to run, and if so begins executing them. Once all the blocks finish, and no further blocks can be executed, the render block is executed. This means that not all blocks may execute. If values required by a block are not ever available, it will not be executed. This behavior simulates an if statement.
All calls to user functions are wrapped in a try/catch block. Any uncaught exceptions are reported on the console with the function name (as registered in the when block) and the input that caused the exception. The error produces something like this on the console:
ERROR: function (Crashes On Purpose) threw an exception (TypeError: Object #<Object> has no method 'crashNow') on input: {
"internal:__ready": 1,
"demo": "a value"
}
Notice that the exact input is reported here so reproducing the error and fixing it is much easier than the typical callback style error.
Docs
Tutorials