2

I am trying to create a new account which contains an inner array but I get an error:

Uncaught Error: The argument passed when initializing an observable array must be an array, or null, or undefined.

Any ideas why this is not working?

<script>
    function Account(id, name, balance, deposits) {
        this.Id = id;
        this.Name = name;
        this.Balance = balance;
        this.Deposits = deposits;
    }
    var myAccountViewModel = function ()
    {
        this.Accounts = ko.observableArray([
              new Account(1, "A1", 100, [1,2]),
              new Account(2, "A2", 200, [2]),
              new Account(3, "A3", 300, [2, 3]),
              new Account(4, "A4", 400, [2,3]),
        ])
    }
    ko.applyBindings(myAccountViewModel);
</script>

HTML

<table>
    <thead>
        <tr>
            <th>S.No</th>
            <th>ID</th>
            <th>Name</th>
            <th>Balance</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: {data:Accounts, as:'Account'}">
        <tr>
            <td data-bind="text:($index()+1)"></td>
            <td data-bind="text:Account.Id"></td>
            <td data-bind="text:Account.Name"></td>
            <td data-bind="text:Account.Balance"></td>
            <!--<td>
                <ul data-bind="foreach: {data:Deposits, as:'Amount'}">
                    <li data-bind="text:(Account().Name + 'Deposited ' + Amount())"></li>
                </ul>
            </td>-->
        </tr>
    </tbody>
</table>
alwaysVBNET
  • 3,150
  • 8
  • 32
  • 65
  • 1
    I can't recreate your error. Tried your code but instantiated a myAccountViewModel then applied bindings to that. Did not get the error you describe. Can you include the associated html? – KolaB Feb 20 '18 at 11:54
  • Is it the lack of `new` in `ko.applyBindings(myAccountViewModel);` ? – user3297291 Feb 20 '18 at 12:03
  • @KolaB I have added the HTML. Please note that I get the error even though the html is commented out. – alwaysVBNET Feb 20 '18 at 12:08
  • @alwaysVBNET - Your code works for me! I used KO 3.4.2 and I placed your script section towards after the table section ... no errors in console (Chromium 64.0.3282.140 Built on Ubuntu , running on Ubuntu 16.04) – KolaB Feb 20 '18 at 12:13
  • When running your code in 'strict' mode I got an error about initialising a property of undefined. I made some minor changes to your code to get this version working (setting `this` to `self` in two places and using the `new` keyword when applying binding). I can post that as a possible answer if you're still stuck. – KolaB Feb 20 '18 at 12:43
  • @KolaB can you please show your code? – alwaysVBNET Feb 20 '18 at 13:40
  • @user3297291 I tried with the 'new' but no luck! – alwaysVBNET Feb 20 '18 at 13:41

1 Answers1

1

The code in the question worked for me. Below is a version that works for @alwaysVBNET. - It's basically the content of the code in the question with some minor modifications. I downloaded KO 3.4.2 from http://knockoutjs.com/downloads/knockout-3.4.2.js

The main change is the use of the temp variable to instantiate Account objects before adding them to the observable array. I will be interested if someone can explain why this should make a difference.

<!doctype html>
<html>
<head>
<title>KO js test</title>
<script src=./knockout-3.4.2.js></script>

</head>
<body>
<table>
    <thead>
        <tr>
            <th>S.No</th>
            <th>ID</th>
            <th>Name</th>
            <th>Balance</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: {data:Accounts, as:'Account'}">
        <tr>
            <td data-bind="text:($index()+1)"></td>
            <td data-bind="text:Account.Id"></td>
            <td data-bind="text:Account.Name"></td>
            <td data-bind="text:Account.Balance"></td>
            <td>
                <ul data-bind="foreach: {data:Deposits, as:'Amount'}">
                    <li data-bind="text:(Account.Name + 'Deposited ' + Amount)"></li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>
<script>
    "use strict";
    function Account(id, name, balance, deposits) {
        var self = this;
        self.Id = id;
        self.Name = name;
        self.Balance = balance;
        self.Deposits = deposits;
    }
    var MyAccountViewModel = function ()
    {
        var self = this;
        self.Accounts = ko.observableArray();
        var temp = new Account(1, "A1", 100, [1,2]);
        self.Accounts.push(temp);
        temp = new Account(2, "A2", 200, [2]);
        self.Accounts.push(temp);
        temp = new Account(3, "A3", 300, [2, 3]);
        self.Accounts.push(temp);
        temp = new Account(4, "A4", 400, [2,3]);
        self.Accounts.push(temp);
    }
    ko.applyBindings(new MyAccountViewModel());
</script>
</body>
</html>
KolaB
  • 501
  • 3
  • 11
  • I have copied/pasted your code and I'm still getting the same error! Unreal. I'm using the same version of Knockout. – alwaysVBNET Feb 20 '18 at 17:01
  • What versions are your os and browser? – KolaB Feb 20 '18 at 17:07
  • Have you tried creating an empty array and pushing the items to it i.e. `var self.Accounts = ko.observableArray();` `var temp = new Account(1, "A1", 100, [1,2]);` `self.Accounts.push(temp);` – KolaB Feb 20 '18 at 17:17
  • no error with the above way. So maybe this could be the answer? Can you edit your answer and also uncommend the which the Deposits are supposed to be shown? – alwaysVBNET Feb 21 '18 at 10:50