Search code examples
knockout.jsknockout-2.0knockout-mapping-plugin

Knockout Mapping Issue


i am new to Ko and mapping plugin.

I have to read data from weather api of a city from http://api.openweathermap.org/data/2.5/history/city?q=Vancouver,%20ca

and display it in UI using ko and mapping.

However I have a issue in mapping and due to that the data is not appearing in UI.

ko.mapping.fromJS(models, self.ArrayOfModels);
http://jsfiddle.net/balain/ENMGp/536/

Thank you in advance.


Solution

  • First off, your fiddle uses a truly outdated version of knockout (1.2.1 is ancient). I've updated it to 3.2.0. Also you don't need the jQuery template plugin for anything. I've removed it.

    Next, I would recommend constructing your view models in such a way that they take care of themselves, including bootstrapping from init data. Like so:

    // Contained Model
    function SearchResultModel(init) {
        // data
        this.message = ko.observable();
        this.cod = ko.observable();
        this.city_id = ko.observable();
        this.calctime = ko.observable();
        this.cnt = ko.observable();
        this.list = ko.observableArray();
    
        // init
        ko.mapping.fromJS(init, {}, this);
    }
    

    Next, you can condense your Ajax request quite a bit:

    // View Model
    function WeatherViewModel(init) {
        var self = this;
    
        // data
        self.city = ko.observable();
        self.searchResult = ko.observable(new SearchResultModel());
    
        // methods
        self.getWeatherByCity = function () {
            var city = self.city()
            if (city) {
                $.get('http://api.openweathermap.org/data/2.5/history/city', {
                    q: city
                }).done(function(data) {
                    self.searchResult(new SearchResultModel(data));
                }).fail(function () {
                    alert("could not get weather data!");
                });
            } else {
                // no city? => empty the search result
                self.searchResult(new SearchResultModel());
            }
        };
    
        // init
        ko.mapping.fromJS(init, {}, self);
    }
    

    init with sample data:

    ko.applyBindings(new WeatherViewModel({
        city: "Vancouver, CA"
    }));
    

    and you are good to go: http://jsfiddle.net/ENMGp/539/.

    Since you tagged this [knockout-2.0] (I have no idea why you would want that for a new project), I've created a 2.0 compatible version: http://jsfiddle.net/ENMGp/540/. The code is the same, but knockout 2.0 does not work with jQuery 1.9+, so I had to downgrade both libraries. FWIW, I'd recommend going with a current release of knockout.