Sapinder Singh
Sapinder Singh

Reputation: 351

exported object returns "undefined"

I have file main.js-

import Maze from "./mazeContainer.js";

let MyMaze;
....
initiate();
....
function initiate() {
    MyMaze = new Maze(Ctx, Width, Height, CustomGrid[0].value, CustomGrid[1].value);
    MyMaze.setup();
    listenMoves();
}
....
export default MyMaze.player;

When I import Player in another file, the Player is undefined.

To say where I define MyMaze.player, it's inside Maze class-

class Maze(arguments....) {
    ....
    setup() {
        ....
        this.drawMap();
    }
    drawMap() {
        ....
        this.player = new Player();
        this.player.setPlayer();
    }
    ....
}

Before this, I had everything inside the same file, and everything was working well. Now when I want to export MyMaze.player to move-detection.js. But here in move-detection.js

import Player from "./main.js";

Player doesn't seem to be defined.

I guess I'm doing something wrong with the export. What's the issue with it? Here's the link to project- https://codesandbox.io/s/maze-p2pyo

Upvotes: -1

Views: 126

Answers (2)

Sapinder Singh
Sapinder Singh

Reputation: 351

Hey I figured out the reason for MyMaze.player not having been defined by the time compiler reaches the export statement at the end of main.js. You see when I call initiate()-

function initiate() {
    MyMaze = new Maze(Ctx, Width, Height, CustomGrid[0].value, CustomGrid[1].value);
    MyMaze.setup();
    listenMoves();
}

Now MyMaze.setup(), after it's performed its job, calls drawMap()-

setup() {
    ....
    this.drawMap();
}

And lastly, drawMap() was using requestAnimationFrame() for each iteration-

drawMap() {
    ....
    if (this.stack.length === 0) {
        // set player
        this.player = new Player(this);
        this.player.setPlayer();
    }
    ....
    window.requestAnimationFrame(()=> this.drawMap());
}

And here's the reason for the issue- requestAnimationFrame().

As requestAnimationFrame() is asynchronous, this means that after drawMap is run for the first time, the execution goes out to listenMoves()-

function initiate() {
    ....
    listenMoves();
}

So while drawMap() is still running and player has not been setup yet, the execution reaches to the end of main.js-

export default MyMaze.player;

And this gives me-

TypeError: undefined has no properties

The fix was to either drop requestAnimationFrame() and directly call this.drawMap()

or instantiate playerinside setup() before drawMap() gets called.

I hope I'm made the correct assumption! Cheers!

Upvotes: 0

Edub
Edub

Reputation: 540

    if (this.stack.length === 0) {
        this.goal = this.currentCell;
        this.drawGoal(this.goal);

        // set player
        this.player = new Player(this);
        this.player.setPlayer();

        // remove Preparing Screen
        document.querySelector(".resetting-grid").classList.remove("show");
        return;
    }

That's the condition to set the player. The stack is initialized with [] and not filled in the process - drawMap() is called but will not go into the condition to set the player. So it's expected to hit an undefined value.

Not sure about the code but I would initialize the player in the setup() method and only set the player in the condition. Not sure about the rest of the code and assumptions made about an present/absent player object.

Upvotes: 1

Related Questions