KnockoutJS and Netflix ODATA

Data-binding with manual mapping

by shelbyz

HTML

<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0rc.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<body> 
    <h2>Search Netflix for Movies</h2> 
    
    <input data-bind="value: search, valueUpdate: 'afterkeydown'" />
    <button data-bind='click: searchClick'>Search</button>
    <br/><br/>
    <textarea data-bind='text: query' cols="75" rows="6"></textarea>
    <br/><br/>
    <b>Movies found <label data-bind="text: movieCount"/></b>
    <br/><br/>
    
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Release Year</th>
                <th>Runtime</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: movie">
            <tr>
                <td data-bind="text: Name" />
                <td data-bind="text: ReleaseYear" />
                <td data-bind="text: Runtime" />
            </tr>
        </tbody>
    </table>
</body>

CSS

table th { text-align:left; padding-right: 3em; font-style:italic }body { font-family: Helvetica, Arial }
input:not([type]), input[type=text], input[type=password], select { background-color: #FFFFCC; border: 1px solid gray; padding: 2px; }

JavaScript

//debugger;

var viewModel = function() {
    var _self = this;
    
    this.movieCount = ko.observable(0);
    this.search = ko.observable("");
    this.query = ko.observable("");
    this.movie = ko.observableArray();
    
    this.addMovie = function(name, runtime, releaseYear) {
        _self.movie.push({Name: name, Runtime: runtime, ReleaseYear: releaseYear});
    };
    
    this.callback = function(result) {
        var movies = result["d"]["results"];

        if (movies === null || movies === 0) {
            alert("no movie results, try again");
        }
        else {
            _self.movieCount(movies.length);
            
            for (var i = 0; i < movies.length; i++) {
                
                _self.addMovie(movies[i].Name, movies[i].Runtime, movies[i].ReleaseYear);
            }
        }
    };
    
    this.searchClick = function() {
        _self.query("http://odata.netflix.com/v2/Catalog/Titles?$select=NetflixApiId,Name,Runtime,ReleaseYear&$filter=substringof('" + _self.search() + "',Name)&$orderby=Name&$callback=?&$format=json");

        $.ajax({
            dataType: "jsonp",
            url: _self.query(),
            success: this.callback,
            error: function(XHR, textStatus, errorThrown) {
                alert(textStatus + ":" + errorThrown);
            }
        });
    };
};

ko.applyBindings(new viewModel());