0

I am trying to make a grid for a game, and I set up the grid, but when I use a for loop to display all of the cells it gives me an error - Uncaught TypeError: Cannot convert undefined or null to object. I think that there is something undefined in the grid array but there shouldn't be. Another theory is that the grid is empty, although it should have 16 cells in it.

let bgCol = '#A6A6A6';
let rows = 4;
let cols = 4;
let grid = [];
let size = 50;


function setup() {
    createCanvas(windowWidth, windowHeight);
    background(bgCol);
    for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
            grid.push(new Cell({x: r * size, y: c * size}, 0));
        }
    }
}

function draw() {
    background(bgCol);
    for (let g of grid) {
        grid[g].dis();
    }
}

class Cell {
    constructor(pos, num, col = '#FFFFFF') {
        this.pos = pos;
        this.num = num;
        this.col = col; // White as placeholder until later
    }
    dis() {
        stroke('#000000');
        strokeWeight(2);
        fill(this.col);
        square(this.pos.x, this.pos.y, size, 5);
        if (this.num) {
            textSize(size - 5);
            text(this.num, this.pos.x + 5, this.pos.y + 5);
        }
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>

3
  • 2
    The error tells you the problem: TypeError: grid[g] is undefined. If you print(g) above the crash, it shows that it's a Cell itself, not an index as you assume. So use g.dis(). Better naming helps avoid the misunderstanding: for (const cell of grid) { cell.dis(); }. Also suggest renaming dis to display. Commented Apr 29 at 18:13
  • @ggorlen Thank you! Although, I was wondering - is there a particular reason that you would use const instead of let or var? Commented Apr 30 at 16:00
  • 2
    Avoid var because it's reassignable and function-scoped, leading to bugs. const prevents reassignment, so you have the stronger guarantee that you won't reassign the value as you do with let. Generally always use const except for rare cases when you need to reassign, you can then use let. Commented Apr 30 at 16:37

1 Answer 1

2

for...of iterates over values, not indexes. for...in, on the other hand, iterates over indexes.

In your case, simply change the line (grid[g].dis();) to g.dis();:

let bgCol = '#A6A6A6';
let rows = 4;
let cols = 4;
let grid = [];
let size = 50;


function setup() {
    createCanvas(windowWidth, windowHeight);
    background(bgCol);
    for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
            grid.push(new Cell({x: r * size, y: c * size}, 0));
        }
    }
}

function draw() {
    background(bgCol);
    for (let g of grid) {
        g.dis();
    }
}

class Cell {
    constructor(pos, num, col = '#FFFFFF') {
        this.pos = pos;
        this.num = num;
        this.col = col; // White as placeholder until later
    }
    dis() {
        stroke('#000000');
        strokeWeight(2);
        fill(this.col);
        square(this.pos.x, this.pos.y, size, 5);
        if (this.num) {
            textSize(size - 5);
            text(this.num, this.pos.x + 5, this.pos.y + 5);
        }
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>

As @ggorlen pointed out in a comment, better naming will help avoid future misunderstandings: change g to cell and dis to display.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.