#

# Example: DataSource with Offline Cache

The DataSourceCache plugin enables caching on any DataSource to reduce high-latency calls to remote sources and to reduce server load. The plugin can point to `Y.OfflineCache` to allow cached data to persist across browser sessions in browsers that support HTML5 localStorage.

###### Look up github repositories by username (ex. lsmith, davglass, or rgrove):

Use the `plug()` method to initialize the DataSourceCache plugin and point the configuration value `cache` to Y.CacheOffline to enable offline caching. The configuration value `expires` can be set to change how soon the data expires.

    YUI().use("datasource", "dataschema", "cache", function(Y) {
        var callback = {
                success: function (e) { /* output to screen */ },
                failure: function (e) { /* output to screen */ }
            },

            myDataSource = new Y.DataSource.Get({
                source: "https://api.github.com/users/",

                // this is only needed because the query appends the url
                // rather than the url's query params
                generateRequestCallback: function (guid) {
                    return '/repos?callback=YUI.Env.DataSource.callbacks.' + guid;
                }
            }),

        myDataSource.plug(Y.Plugin.DataSourceJSONSchema, {
            schema: {
                resultListLocator: "data",
                resultFields: ["name"]
            }
        });

        // Enable offline data caching by pointing to Y.CacheOffline.
        // For demonstration purposes, data is set to expire after 10 seconds
        myDataSource.plug(Y.Plugin.DataSourceCache, {
            cache: Y.CacheOffline,
            expires: 60000, // 1 min.
            max: 5
        });

        // Retrieves from server. Adds to cache
        myDataSource.sendRequest({
            request : "lsmith",
            callback: callback
        });

        // Retrieves from server. Adds to cache
        myDataSource.sendRequest({
            request : "davglass",
            callback: callback
        });

        // Retrieves from cache if requested within 5 seconds
        myDataSource.sendRequest({
            request : "lsmith",
            callback: callback
        });

        // ... wait 60 seconds ...

        // Cached data has expired. Retrieves from server. Adds to cache.
        myDataSource.sendRequest({
            request : "davglass",
            callback: callback
        });
    });

### Full Example Source Listing

    <form id="demo" action="http://search.yahoo.com/search">
    <h6>Look up github repositories by username (ex. lsmith, davglass, or rgrove):</h6>
    <input type="input" id="demo_input_query" name="p">
    <input type="submit" id="demo_query_retrieve" value="Retrieve data">
    <input type="button" id="demo_cache_clear" value="Clear cache">
    <div id="demo_output_response" class="output"></div>
    </form>

    <script type="text/javascript">
    YUI().use("json-stringify","node", "datasource-get", "datasource-jsonschema", "cache", "datasource-cache", "datatype-date", function (Y) {
    var output = Y.one("#demo_output_response"),
        source = "remote source",

        myDataSource = new Y.DataSource.Get({
            source:"https://api.github.com/users/",
            generateRequestCallback: function (guid) {
                return '/repos?callback=YUI.Env.DataSource.callbacks.' + guid;
            }
        }),

        callback = {
            success: function(e){
                var when = Y.DataType.Date.format(new Date(), {format:"%F %r"}),
                    data = Y.JSON.stringify(e.response, null, 2);

                output.setHTML(
                    "<p>[" + when + "] Retrieved from " +
                    "<strong>" + source + "</strong></p>" +
                    "<pre>" +
                        data.replace(/&/g,"&amp;")
                            .replace(/</g,"&lt;")
                            .replace(/>/g,"&gt;") +
                    "</pre>");
            },
            failure: function(e){
                var when = Y.DataType.Date.format(new Date(), {format:"%F %r"}),
                    message = /fields retrieval/.test(e.error.message) ?
                        "User not found" : e.error.message;

                output.setHTML(
                    "<p>[" + when + "] Could not retrieve data: " +
                        "<em>" + message + "</em>" +
                    "</p>");
            }
        };

    myDataSource.plug(Y.Plugin.DataSourceJSONSchema, {
        schema: {
            resultListLocator: "data",
            resultFields: ["name"]
        }
    });

    myDataSource.plug(Y.Plugin.DataSourceCache, {
        cache: Y.CacheOffline,
        expires: 60000, // 1 min.
        max:5
    });
    myDataSource.cache.on("retrieve", function(){
        source = "cache";
    });

    Y.one("#demo_cache_clear").on("click", function(){
        var when = Y.DataType.Date.format(new Date(), {format:"%F %r"});

        myDataSource.cache.flush();
        output.setHTML("<p>[" + when + "] Cache cleared.</p>");
    });

    Y.on("submit", function(e){
        e.halt();
        var query = encodeURIComponent(
                        Y.one("#demo_input_query")
                            .get("value")
                            .replace(/"/g,'\\"')
                            .replace(/\W/g, ''));

        if(query) {
            source = "remote source";
            myDataSource.sendRequest({
                request:query,
                callback:callback
            });
        } else {
            output.setHTML("<p>Please enter a query.</p>");
        }
    }, "#demo");
    });
    </script>