8

I am trying to add elements from the server to observable array in knockout.

Here is my ViewModel:

function ArticlesViewModel() {
    var self                = this;
    this.listOfReports      = ko.observableArray([]);

    self.loadReports = function() {
        $.get('/router.php', {type: 'getReports'}, function(data){
            for (var i = 0, len = data.length; i < len; i++){
                self.listOfReports.push(data[i]);
            }
        }, 'json');
    };

    self.loadReports();
};

And it works perfectly. But I know that I can merge two arrays in javascript using concat() and as far as I know concat works in knockout. So when I try to substitute my for loop with self.listOfReports().concat(data); or self.listOfReports.concat(data); , nothing appears on the screen.

In the first case there is no error, in the second error tells me that there is no method concat.

So how can I concat the data without my loop. And I would be really happy to hear why my method was not working

Community
  • 1
  • 1
Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • 1
    observableArrays do not support the concat method, there's an open issue on this: https://github.com/knockout/knockout/issues/786 – Tanner Feb 21 '14 at 10:17
  • Strange, because I thought that in [this question](http://stackoverflow.com/q/19221174/1090562) a person is concating observable array. So as far as I understood the approach I took (looping and pushing) is the best one? – Salvador Dali Feb 21 '14 at 10:29
  • I might be wrong then, I always tend to use the loop/push method – Tanner Feb 21 '14 at 10:30
  • 1
    @Tanner It looks like you will learn something new from my question and mostly nemesv's answer :-) – Salvador Dali Feb 21 '14 at 10:36

2 Answers2

14

The observableArray does not support the concat method. See the documentation for the officially supported array manipulation methods.

However what you can do is to call concat on the underlying array and then reassign this the new concatenated array to your observable:

self.listOfReports(self.listOfReports().concat(data));

The linked example works because the self.Products().concat(self.Products2()) were used in a loop. If you just write self.listOfReports().concat(data); it still concatenates but you just thrown away the result and don't store it anywhere, that is why you need to store it back to your observableArray.

Community
  • 1
  • 1
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • This is something should be included in KO core also. – Nish Sep 29 '14 at 10:17
  • 1
    A little more efficient approach is to use the push method like so: `self.listOfReports.push.apply(self.listOfReports, data)` – csnate Apr 11 '16 at 21:51
0

another way to concat array in mobx:

const arr = [...self.data, ...result.data.data.customers]
self.data.replace(arr)
Mr. Tuan
  • 85
  • 1
  • 6