Search code examples
javascriptobjectprototype

Javascript object property returns as undefined only when called from inside another function


I created 3 objects that nest arrays of one another - we'll call them Table, Row and Column so I can show you what's wrong. Table has an array of Rows, and Row has an array of Columns. When I call properties of the Rows from Table, no problem. When I call properties of the Columns from Row, it says undefined, but in the debugger and the console it recognizes the object and it's properties. Maybe I've been staring at it too long but I can't see a fundamental difference.

I stripped the Table layer to be sure it wasn't an issue with nested objects. Here's the code, not working:

  function Column()
  {
    this.sampleProp = "testprop";
    this.content =  "<td>sometext</td>";
  }
  function Row(columns)
  {
    this.columns = [];
    this.columns = columns;
    this.outputRows = function() 
                      {
                        var temp = "<tr>";
                        for(var i = 0; i < this.columns.length; i++)
                        {
                          //this is the line that doesn't work and comes out as undefined:
                          temp += this.columns[i].content;
                          console.log("Problem: " + this.columns[i].content);
                          //yet the object exists, and has the correct properties:
                          console.log(this.columns[i]);
                        }
                        temp += "</tr>";
                        return temp;
                      };
  }
  function test()
  {
    var col = new Column();
    console.log("Printing out the value from here works fine: " + col.content);
    var cols = [col];
    console.log("It's also fine when it's called from an array: " + cols[0].content);
    var row = new Row([cols]);
    console.log(row.outputRows());
  }

Here is the interaction between the parent layer and the rows, working fine:

  function Table(rows)
  {
    this.rows = [];
    this.rows = rows;
    this.outputTable = function() 
                       {
                         var temp = "<table>";
                         for(var i = 0; i < this.rows.length; i++)
                         {
                           temp += this.rows[i].outputRows();
                         }
                         temp += "</table>";
                         return temp;
                       };
  }

and the updated test function:

  function test()
  {
    var column = new Column();
    var cols = [column];
    var row = new Row([cols]);
    console.log(row.outputRows());
    var rs = [row, row];
    var table = new Table(rs);
    console.log(table.outputTable());
  }

Two rows print out as expected this way, with undefined inside each. I originally had column.content written as a function, it doesn't make a difference.

Please tell me what stupid mistake I'm missing here!


Solution

  • Change that line :

         var row = new Row([cols])
    

    into

         var row = new Row(cols)
    

    since cols is already an array, you don't need to put it in an array again.

    function Column() {
      this.sampleProp = "testprop";
      this.content = "<td>sometext</td>";
    }
    
    function Row(columns) {
      // removed this.columns = [] since you are assigning it in the next line
      this.columns = columns;
      this.outputRows = function() {
        var temp = "<tr>";
        for (var i = 0; i < this.columns.length; i++) {
          //this is the line that doesn't work and comes out as undefined:
          temp += this.columns[i].content;
        }
        temp += "</tr>";
        return temp;
      };
    }
    
    function test() {
      var col = new Column()
      console.log("Printing out the value from here works fine: " + col.content);
      var cols = [col];
      console.log("It's also fine when it's called from an array: " + cols[0].content);
      var row = new Row(cols); // the problem was here
      console.log(row.outputRows());
    }
    
    test()