To interaction with the dtime API via Javascript, you need to be able to chain together API calls in a straightforward manner.
Hypermedia APIs rely on state machine logic - given a current state, there are a number of transitions you can make (Valid HTTP verbs on the available rels)
In the code, transition(current_state, rel, opts) is our way to transition.
where opts has some properties:
opts.uriVariables: optional variables to go into a uri template.opts.data: optional data to send with requestopts.method: which http method to use (maybe default get)opts.success: callback to attach on success, takes in the json responseopts.error: callback to attach on error, takes in the json response
transition will internally use ajax_call(url, method) to make the initial ajax
call. The below method will work with both jquery and zepto. For other options, you'd
need to change $.ajax to whatever format your XHR requests usually take.
transition internally relies on the href_for function, you pass the current_state
variable in and find the link from that state object.
href_for(current_state, rel, uri_variables)
Href for loops through current_state._links and finds the link with a name == "rel" It uses uri template syntax to turn /questions/{question_id} into /questions/foo, if uri_variables.question_id = "foo".
In 1.5, jQuery introduced deferred objects - for chaining together multiple api calls, it's a really handy pattern. Read more about them here - http://api.jquery.com/category/deferred-object/
The above code uses a simple library to duplicate jquery deferred functionality: https://github.com/sudhirj/simply-deferred
It's an optional way to help clean up the way callbacks are chained together:
transition a, "b", success: (b)->
transition b, "c", success: (c)->
console.log(c)vs
transition(a, "b").done (b)->
transition(b, "c").done (c)->
console.log(c)The added benefit is that multiple done functions may be chained onto a deferred object, and that deferred object can even have done functions called on it after it's succeeded - those done callbacks will just immediately fire.
You can see this pattern used in the load_root() function, and the load_sitemap() function. These
functions allow you to make one AJAX request for the sitemap to service any number of requests, by
just chaining more done functions onto load_sitemap().done()
Deferreds also allow pipe:
transition(a, "b")
.pipe((b)-> transition(b, "c"))
.done((c)-> console.log(c))Which enforces the order of multiple ajax calls in the order they are piped.