-3

I'm collecting an array of data, saving it as array of custom objects, then trying to map it to a table. I have a constructor for my object type:

function cellData(x, value, y){
    this.x = x;
    this.value = value;
    this.y = y;
}

After gathering the data into an array of cellData objects, and i've already determined the necessary size of the table, I have two nested loops to loop through column/row and and map my data to a table:

for (var y2 = 0; y2 < yMax; y2++){
      tableHtml += '<tr>';
      for (var x2 = 0; x2 < xMax; x2++){
        var cellMatch = new cellData();
        cellMatch = cells.filter(cd => {
          return cd.x == x2 && cd.y == y2 && cd.value;
        });
        console.log(cellMatch.value);
        if (cellMatch != undefined) {
          tableHtml += '<td>' + cellMatch.value + '</td>';
        } else {
          tableHtml += '<td> </td>';
        }
      }
      tableHtml += '</tr>';
    }

The issue i'm running into is I'm having trouble with my data output, and accessing the properties of my cellData objects. In my console logging, if I try to just log cellMatch on its own, I get the whole object. But when I try to log the value property, i'm getting undefined. What am I doing wrong here?

New contributor
Ryan Tanner is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • @PeterPointer this should not have been published from the Staging Ground while it was still tagged as needing Major Changes...is there a reason why you ignored that and still published it? The code provided isn't runnable (missing code, and no sample data), the description of the output they're seeing was unspecific/incorrect, and it was becoming clear that it was basically a duplicate question. All this was documented in the Staging Ground comments. Now the OP got downvotes - that could have been avoided. Commented Mar 26 at 10:56
  • The underlying issue was clear. They were misunderstanding that they overwrite the cellMatch variable, independent of any other "problem" with the question. They got downvotes because people here are annoyed with beginners and gatekeep until the perfect question is made for some reason. There is a clear bug in the source code posted, that's what they wanted to know. Maybe staging ground should be a 3/3 vote then like when closing questions. Commented Mar 26 at 14:17

2 Answers 2

2

The .filter function returns an array, not an object.

var cellMatch = new cellData(); // <-- New object of type `cellData`
cellMatch = cells.filter(...); // <-- Overwrites `cellMatch` with an array

JavaScript does not keep the type of a variable, for example merge the right side with the left side.
It will instead just be a different variable of the type you assign it.

You can see in the documentation of .filter() that it returns an array:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

You probably intended to use .find()?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

I can't make out what type .value is here, but for example you could .find() the object, but if it doesn't exist create it:

var cellMatch = cells.find(cd => cd.x == x2 && cd.y == y2) || new cellData(x2, 0, y2);

Instead of 0, just use whatever default you want for .value - '' works, too to not print anything.

You can use your browser developer tools to step through the code line by line. You would have seen how cellMatch changes.
console.log is useful until a point, but you also don't want a call like that on every line.

Sign up to request clarification or add additional context in comments.

Comments

0

Your question and your code don't quite match up. You say: "an array of cellData objects*", but then, inside the for loops, you create new CellData objects, which you then instantiate again by calling filter on cells (which I assume is the array you mentioned and which, as Peter Pointer correctly points out, returns an array). I think what you want to do is the following:

for( var y2 = 0; y2 < yMax; y2++ ) {
   tableHtml += '<tr>';
   for( var x2 = 0; x2 < xMax; x2++ ) {

        // we take the *CellData* object contained in the array
      var cellMatch =  cells[ x2 ][ y2 ];
      console.log(cellMatch.value);
      if( cellMatch != undefined ) {
         tableHtml += '<td>' + cellMatch.value + '</td>';
      }
      else {
         tableHtml += '<td> </td>';
      }
   }
   tableHtml += '</tr>';
}

8 Comments

According to the code in the question, there isn't a 2D array (or map/dictionary as an object) of cells, so var cellMatch = cells[ x2 ][ y2 ] won't retrieve anything. Assuming cells is a simple 1D array of cellMatch objects, then the code would retrieve an item at a random index in that array (since it's unlikely they'd be index by the coordinates) and then attempt to get a property of that cellMatch which is another number. And cellMatch doesn't have numeric properties, so the result will be either undefined or an error if x2 is out of bounds of the array.
The OP say: "After gathering the data into an array of cellData objects", this leads me to believe that cells is an array of CellData objects,...
you say: "and then attempt to get a property of that cellMatch which is another number. And cellMatch doesn't have numeric properties, so the result will be either undefined or an error if x2 is out of bounds of the array", CellData has three attributes: x, value, and y. Are they numeric? I don't know, and it doesn't matter in this context. On the other hand, if, as you suggest, x2 or y2 don't “stay within the matrix boundaries”... we'd have to take the glass of wine away from the OP :)
"has three attributes: x, value, and y. Are they numeric? I don't know" it makes no difference what the values are. The property *names are what you listed. data[ y2 ] is not going to match any of them because y2 is a number. Therefore data[ 42 ] will return undefined for any data = { x: <anything>, y: <anything>, value: <anything> }.
Where do you see data[ y2 ] in my code?
"this leads me to believe that cells is an array of CellData objects" yes - an array of objects, sure. But it doesn't follow that it's a 2D array indexed by the x/y coordinates of the object. So, it's very likely going to look like this: [ new cellData(1, "foo", 2), new cellData(4, "bar", 2) ]. Trying to fetch arr[4][2] from there is an error. Fetcing arr[1][2] is undefined.
It's true that there's a possibility that cells isn't two-dimensional; the presence of nested for loops seems to suggest otherwise, but I think it's best to set aside speculation and wait for the OP's response :)
The presence of nested for loops is because they walk through the whole coordinate space but the coordinates are used to look up an object in a single dimensional array. suggestion to hold off on speculation is good - you should heed it. Because I've been going off the information presented, you've been the one speculating.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.