JBoyus
JBoyus

Reputation: 25

Knockout: Mapping of data not working with filter function

Basically I'm very new to Knockout. I have been trying tons and tons of examples and I'm going insane now. What I'm doing is not difficult. But, it still doesn't work.

I'm trying to take in data, map it to an object (?), then using some observables to do different filtering. This data will never need to be written back to the server, it is for consumption only.

My broken example: http://jsfiddle.net/boyus/qTb5Q/3/

function Item(id, firstName, lastName, expertise, img, tag) {
    this.id = ko.observable(id);
    this.firstName = ko.observable(firstName);
    this.lastName = ko.observable(lastName);
    this.expertise = ko.observable(expertise);
    this.img = ko.observable(img);
    this.tag = ko.observable(tag);
    this.fullName = ko.dependentObservable(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
    this.expertPath = ko.dependentObservable(function() {
        return "http://www.example.com/user/" + this.id();
    }, this);
    this.imgPath = ko.dependentObservable(function() {
        return "http://img835.imageshack.us/img835/5116/" + this.img();
    }, this);
}

var viewModel = {
    items: ko.observableArray([]),
    filter: ko.observable()
};

//ko.utils.arrayFilter - filter the items using the filter text
viewModel.filteredItems = ko.dependentObservable(function() {
    var filter = this.filter().toLowerCase();
    if (!filter) {
        return this.items();
    } else {
        return ko.utils.arrayFilter(this.items(), function(item) {
            return (item.fullName().indexOf(filter) > -1);
        });

    }, viewModel);


var JSONdataFromServer = '[{"id":"1","firstName":"Bill","lastName":"Nye","expertise":"Science Guy", "img":"emptyprofile.png","tag":"environment"},{"id":"54","firstName":"John","lastName":"Dow","expertise":"Software Creation","img":"emptyprofile.png","tag":"software"},{"id": "544","firstName":"Pete","lastName":"Dragon","expertise":"Magic (and Sparkles)","img":"emptyprofile.png","tag": "environment"}]';

var dataFromServer = ko.utils.parseJson(JSONdataFromServer);

//do some basic mapping (without mapping plugin)
var mappedData = ko.utils.arrayMap(dataFromServer, function(item) {
    return new Item(item.id, item.firstName, item.lastName, item.expertise, item.img, item.tag);
});


viewModel.items(mappedData);

ko.applyBindings(viewModel);​

Thanks for all the help in advance.

If it helps (aka my code will never work) my future updates to this code will be:

Upvotes: 1

Views: 1392

Answers (1)

RP Niemeyer
RP Niemeyer

Reputation: 114792

For the specific problems with your current fiddle:

  • you were missing a brace in the filteredItems at the end of the else statement
  • you can't call toLowerCase() on null or undefined. I changed it to initialize filter as an empty string.
  • the comparison probably should convert fullName to lower case as well.

Updated sample here: http://jsfiddle.net/rniemeyer/qTb5Q/4/

Upvotes: 1

Related Questions