mohsinali1317
mohsinali1317

Reputation: 4425

Merging arrays in Knockout

In my knockout app I have two observable array. One is Location,

self.locations = ko.observableArray([]).withIndex('id');

This contains all the locations. The locations can be associated to a project or not. If the locations don't exists in the project it will have project id null.

The other array is of projects. It contains all the projects if they have any location it has an array of locations.

Now what I am trying to do is to get an array with the combination of two something like this

displayLocations = {
  location1 = {name = "abc", ...}
  ... these don't have any projects
  location9 = {name = "xyz", projectName = "project1", .. }
}

I am trying to create a computed property for that and then on the view side I am thinking of using different templates depending upon if the location has project or not.

any suggestions?

Upvotes: 1

Views: 450

Answers (1)

webketje
webketje

Reputation: 10966

Not sure about the withIndex method, but with vanilla KO you can use ko.utils.arrayMap inside a computed:

this.associatedLocations = ko.computed(function() {
  var dataLoc = this.locations(),
      dataProj = this.projects(), 
      result = ko.utils.arrayMap(dataLoc, function(loc) {
         var newObj = loc, project;
         if (loc.projectId !== null) {
            project = ko.utils.arrayFirst(dataProj, function(proj) {
               return proj.id === loc.projectId;
            });
            newObj.projectData = proj;
         }
         return newObj;
      });
  return result;
}, this);
// assumes locations have a 'projectId' & 'name' property, & projects an 'id' property
// will return an array in the form of
// [ {name: 'xyz', projectData: { id: ..., projectName: ...}}]

You can test whether a location is associated with a project by doing:

<div data-bind="template: {
   name: obj.projectData ?  'nameIfProject' : 'nameIfNoProject' }">
</div>

Upvotes: 2

Related Questions