This library makes it possible to get data from a JSONP API. If you are not sure what JSONP is then you probably don't need this, but more information about it can be found here: https://en.wikipedia.org/wiki/JSONP
Define a script tag. This works like any other HTML node in Elm. If a src attribute is passed a resource will be fetched. If plain text is added to the DOM, it will be interpreted as Javascript from the browser who will run it:
script [] [ text "console.log('Hello Elm');" ]
A jsonp event handler. It will emit a Msg with a Value that can be then be handled in the update function. The Value will be the JSON response of the API. A typical use of this model could be:
type Msg
= Response Value
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Response value ->
case (Json.Decode.decodeValue responseDecoder value) of
Ok data ->
Err msg ->
view : Model -> Html Msg
view model =
div []
[ script [ onJsonp Response ] [ text padding ]
, script [ type_ "application/javascript", src "http://www.example.com/api/resource?callback=parseResponse" ] []
]
A default "padding" function which can be used to parse jsonp requests. This exposes two variables to the Window object, paddingScript and parseResponse.
A variation of the default padding function which implements polling. The script tag will be replaced on a successful response after six seconds. Note that if the server does not respond for any reason, the wrapper function will not run and the polling will stop.
module Jsonp exposing
( script
, padding
, polling
, onJsonp
)
{-| This library makes it possible to get data from a JSONP API.
If you are not sure what JSONP is then you probably don't need this,
but more information about it can be found here: https://en.wikipedia.org/wiki/JSONP
# Script Tag
@docs script
# Response event handler
@docs onJsonp
# Helpers
@docs padding, polling
-}
import Html exposing (Html, node, Attribute)
import Html.Events exposing (on)
import Json.Decode exposing (map, at, value, Value)
{-| Define a script tag. This works like any other HTML node in Elm.
If a src attribute is passed a resource will be fetched. If plain text
is added to the DOM, it will be interpreted as Javascript from the browser
who will run it:
script [] [ text "console.log('Hello Elm');" ]
-}
script : List (Attribute msg) -> List (Html msg) -> Html msg
script attributes children =
node "script" attributes children
{-| A default "padding" function which can be used to parse jsonp requests.
This exposes two variables to the Window object, paddingScript and parseResponse.
-}
padding : String
padding =
"""
var paddingScript = document.currentScript;
var parseResponse = function(payload) {
var jsonp = document.createEvent('CustomEvent');
jsonp.initCustomEvent('jsonp', true, true, payload);
paddingScript.dispatchEvent(jsonp);
};
"""
{-| A variation of the default padding function which implements polling. The script tag
will be replaced on a successful response after six seconds. Note that if the server does
not respond for any reason, the wrapper function will not run and the polling will stop.
-}
polling : String
polling =
"""
var paddingScript = document.currentScript;
var parseResponse = function(payload) {
var jsonp = document.createEvent('CustomEvent');
jsonp.initCustomEvent('jsonp', true, true, payload);
paddingScript.dispatchEvent(jsonp);
setTimeout(function() {
currentScript = document.querySelectorAll('#nowPlayingSrc')[0];
var newScript = document.createElement('script');
newScript.id = currentScript.id;
newScript.src = currentScript.src;
newScript.type = currentScript.type;
currentScript.parentNode.replaceChild(newScript, currentScript);
}.bind(this), 6000);
};
"""
{-| A jsonp event handler. It will emit a Msg with a Value that can be then be handled
in the update function. The Value will be the JSON response of the API. A typical use
of this model could be:
type Msg
= Response Value
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Response value ->
case (Json.Decode.decodeValue responseDecoder value) of
Ok data ->
Err msg ->
view : Model -> Html Msg
view model =
div []
[ script [ onJsonp Response ] [ text padding ]
, script [ type_ "application/javascript", src "http://www.example.com/api/resource?callback=parseResponse" ] []
]
-}
onJsonp : (Value -> msg) -> Html.Attribute msg
onJsonp tagger =
on "jsonp" (Json.Decode.map tagger (Json.Decode.at ["detail"] Json.Decode.value))