Cannot read properties of undefined

I am using the Aavegotchi video tutorial to learn to use Moralis. In this tutorial, we are trying to read another player’s position and create an image on the screen for the other player. I’ve typed the code as it is in the video, but it’s giving me the following error:

main.js:124 Uncaught TypeError: Cannot read properties of undefined (reading '0x99767835b88221f59295c2a5ed77cd73f522bc2d')
    at Subscription.<anonymous> (main.js:124)
    at emitTwo (moralis.js:39645)
    at Subscription.emit (moralis.js:39716)
    at LiveQueryClient.value (moralis.js:2007)
    at WebSocket.socket.onmessage (moralis.js:1799)

Here is the relevant block of code:

let user = Moralis.User.current();
let query = new Moralis.Query('PlayerPosition');
let  subscription = await query.subscribe();
subscription.on('create', (plocation) => 
{
  if(plocation.get("player") != user.get("ethAddress"))
  {
    if(competitors[plocation.get("player")] == undefined)
    {
      competitors[plocation.get("player")] = this.add.image(plocation.get("x"),plocation.get("y", 'dude'));
    }
    else
    {
      competitors[plocation.get("player")].x = plocation.get("x");
      competitors[plocation.get("player")].y = plocation.get("y");
    }
    console.log("some dude moved! Get him!");
    console.log(plocation.get("player"));
    console.log("New X: ", plocation.get("x"));
    console.log("New Y: ", plocation.get("y"));
  }
})

Any ideas?

I don’t have an idea now. Do you get same error every time something happens?
Can you isolate to the exact line that gives that error using console.log?

Yes. It gives a new instance of the error any time the remote player moves on either client. I also restarted my http server, but that didn’t do anything.

This is the line giving the error:

if(competitors[plocation.get("player")] == undefined)

I also have this showing on my http server:

::1 - - [14/Nov/2021 00:39:56] "GET /Assets/Ninjas/png/Idle__000.png HTTP/1.1" 304 -
::1 - - [14/Nov/2021 00:39:56] code 404, message File not found
::1 - - [14/Nov/2021 00:39:56] "GET /favicon.ico HTTP/1.1" 404 -

I think that first 404 is just from the favicon.ico, but I’m not sure. The path to the asset before it looks correct and it loads just fine on the primary player.

those 2 things from http server log look fine, the one with assets it means that the data was not modified (304 code) and the second one means that there is no favicon.

for that error, what you get if you use console.log(competitor) before that line?

you can also look in your Moralis server dashboard in logs to see if there is something strange there.

If I print competitor to the console right before that point, it shows undefined, which is expected. For some reason, it looks like it is throwing an error because it is undefined, but that’s how he did it in the video and it worked just fine. Maybe it’s throwing an error because it hasn’t been initialized? But that’s literally what the purpose of the line is, to see if it’s already been initialized and assigned. So I’m a little confused. Maybe there has been some server side code updates that forces this to be done differently or something? By all things I can tell it should work and if it wasn’t supposed to, I’d think visual studio code would flag it.

My server logs look fine. Just new clients, disconnects, and get plugins. No errors.

One client is running on Chrome, one on Edge. Both have the Metamask extension and can succesfully login through the app.

where is that competitors variable defined?

It’s declared further up in the method above some unrelated code with other declarations, and initialized inside the same if statement that’s throwing the error.

var competitors;
.
.
.
.
let user = Moralis.User.current();
let query = new Moralis.Query('PlayerPosition');
let  subscription = await query.subscribe();
subscription.on('create', (plocation) => 
{
  if(plocation.get("player") != user.get("ethAddress"))
  {
    console.log(competitors);
    if(competitors[plocation.get("player")] == undefined)
    {
      competitors[plocation.get("player")] = this.add.image(plocation.get("x"),plocation.get("y", 'dude'));
    }

It’s designed to run this any time any player in the game moves position (inefficient yes, I know. He talks about that later in the video and it does cause lag). Then it checks to see if the player that’s moving is the current player. If not, it checks to see if it’s a player that is already in the array. If not, it stores it in the array as an image with the position of that player. If that player is in the array, it just changes the location of the image to the new location. At least as far as I understand the code. I’m pretty sure I figured out how it works.

this doesn’t look like an initialisation, only a declaration.

Right. The initialization is inside the brackets of the last if statement.

  competitors[plocation.get("player")] = this.add.image(plocation.get("x"),plocation.get("y", 'dude'));

I was wondering if that’s why it was giving an error, but that’s the way he did it in the video and it worked, and Visual Studio doesn’t have a problem with it either.

I tested this in a browser console:

var competitors;
if(competitors["5"] == undefined){ console.log("5") }
=>
VM2624:1 Uncaught TypeError: Cannot read properties of undefined (reading '5')

Ok, so I guess maybe it doesn’t work anymore then :man_shrugging: . Maybe I should just look at some of the newer tutorials on the discord.

maybe some code is missing from what you have there

Ok, there was something missing. The declaration was actually supposed to be like this:

var competitors = {};

I had a few other issues after that, but I was able to solve them on my own. Thanks for your help!