Search code examples
jqueryjsonhtmlknockout.jsknockout-mapping-plugin

Knockout Mapping to image (links) in Json


Still trying to get the Knockout mapping plugin fine tuned. I'm close, but cannot get the image links from the Json (google books api) to display the images. Not sure if I should be trying to go this deep into the Json on the HTML or restructure the mapped data. I'd be happy either way. Thanks in advance for your help.

HTML...

<body>
    <h2>Find Cat in the Hat</h2>
       <div>
            <input id="booksearch" /><input id="btnTest" type="button" value="button" />
        </div>
        <div>
            <table id="bookresults">
                <thead>

                   <tr>
                        <th colspan="6">Books</th>

                    </tr>
                </thead>
                <tbody data-bind="foreach: model.items">
                    <tr>
                        <td><input type="button" title="Select" value="Select" /></td>
                        <td data-bind="text: volumeInfo.title"></td>
                        <td data-bind="text: volumeInfo.description"></td>
                        <td><table><tbody><!-- ko foreach: volumeInfo.industryIdentifiers --><tr><td data-bind="text: identifier"></td></tr><!-- /ko --></tbody></table></td>
                        <td><table><tbody><!-- ko foreach: volumeInfo.categories --><tr><td data-bind="text: $data"></td></tr><!-- /ko --></tbody></table></td>
                        <td><table><tbody><!-- ko foreach: items.volumeInfo --><tr><td><img data-bind="attr: {src: imageLinks.thumbnail}" /></td></tr><!-- /ko --></tbody></table></td>

                    </tr>

                    <tr>
                    </tr>

                </tbody>
            </table>
        </div>
    <script src="/Scripts/jquery-1.8.2.js"></script>
    <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
    <script src="/Scripts/knockout-2.2.0.js"></script>
    <script src="/Scripts/knockout.mapping-latest.js"></script>
    <script src="/Scripts/ireadabook.js"></script>

</body>

js file....

$(document).ready(function () {
    //Knockout Test

    $('#btnTest').click(function () {

        var url = "https://www.googleapis.com/books/v1/volumes?q=the+Cat+In+The+Hat";
        var viewModel = {};
        $.getJSON(url, function (data) {

            viewModel.model = ko.mapping.fromJS(data);
            ko.applyBindings(viewModel);

        });

        //Show the results after selected
        $('#bookresults').css("display", "block");

    });

});

Solution

  • The mapping plugin creates your viewmodel with the same structure as your source. So you need to access the data in your mapped viewmodel as you would access it from the source.

    In your source JSON the imageLinks property looks like this:

    enter image description here

    As you can see imageLinks is not an array but an object ({} instead of []), so you don't need the ko foreach you can just write:

    <table>
         <tbody>
             <tr>
                 <td>
                     <img data-bind="attr: {src: volumeInfo.imageLinks.thumbnail}" />
                 </td>
             </tr>
         </tbody>
    </table>
    

    Demo JSFiddle.