{-# LANGUAGE DeriveDataTypeable, NoImplicitPrelude, PackageImports #-}
{- |
client-side half of a typed AJAX communication channel.
To use this library, you could start by defining a type in a file that
can be shared between the Haskell Server and Fay client. For example:
@
data Command
= SendGuess Guess (ResponseType (Maybe Row))
| FetchBoard (ResponseType (Maybe Board))
deriving (Read, Show, Data, Typeable)
instance Foreign Command
@
The 'ResponseType' argument specifies what type each command should
return. Using GADTs would be cleaner, but Fay does not support GADTs
yet.
To execute a remote function we use the 'call' function:
@
call "/ajax" FetchBoard $ \mboard -> ...
@
Due to the single-threaded nature of Javascript, we do not want to
block until the 'call' returns a value, so we perform the AJAX request
asynchronously. The third argument to 'call' is the callback function
to run when the response is received.
-}
module AJAX where
import "fay-base" Data.Data
import FFI
import JQuery
import ResponseType
import "fay-base" Prelude
-- | Asynchronously call a command
--
-- Note: if the server returns 404 or some other non-success exit
-- code, the callback function will never be run.
--
-- This function is just a wrapper around 'ajaxCommand' which uses the
-- 'ResponseType res' phantom-typed parameter for added type safety.
call :: String -- ^ URL to 'POST' AJAX request to
-> (ResponseType res -> cmd) -- ^ AJAX command to send to server
-> (res -> Fay ()) -- ^ callback function to handle response
-> Fay ()
call uri f g = ajaxCommand uri (f ResponseType) g
-- | Run the AJAX command. (internal)
--
-- You probably want to use 'call' which provides additional
-- type-safety.
--
-- Note: if the server returns 404 or some other non-success exit
-- code, the callback function will never be run.
--
-- see also: 'call'
ajaxCommand :: String -> Automatic cmd -> (Automatic res -> Fay ()) -> Fay ()
ajaxCommand =
ffi "jQuery['ajax']({'url': %1, 'type': 'POST', 'data': { 'json' : JSON.stringify(%2) }, 'dataType': 'json', 'success' : %3 })"