0

While create the skeleton for an HTML 5 game (using canvas), I noticed an interesting quirk about the JavaScript language that I don't seem to quite understand!

Specifically, I created an array of objects (nodes) which I have no problem passing through functions (as "node"), but even after confirming that said object is recognized in the console log, the .indexOf() method doesn't seem to recognize said object as an item in the array (giving me the generic "-1" output).

function StartGame(){
	//Initiating draw variables
	cx = document.getElementById("GameMap")
	seeds = cx.getContext("2d")
	//Resetting nodes
	nodes = []
	GenNodes() //randomly generates and scatters new connector nodes on the game-map
}

function GenNodes() {
		for (i=0; i<10; i++) {
		nodes[i]= new SeedNode()
		}
}

function SeedNode() {
		this.shape = "circle"
		this.radius = "10"
		this.x = 730*Math.random() + 10
		this.y = 730*Math.random() + 10
		DrawNode(this,this.x,this.y)
} 

function DrawNode(node,x_cen,y_cen) {
	console.log(node)
	console.log(nodes.indexOf(node))
	seeds.beginPath();
	seeds.arc(x_cen,y_cen,10,0,2*Math.PI);
	seeds.stroke();
	seeds.fillText(nodes.indexOf(node),x_cen,y_cen)
}
<!DOCTYPE html>
<html>
<head>
<title>ScatterDots! the StackOverFlow Edition</title>
<script src="ScatterDots.js"></script>
</head>

<body onload='StartGame()'>
	
<canvas id="GameMap" width="750" height="750" style="border:1px solid #000000"></canvas>

</body>

</html>

My (rather unsophisticated) guess is that objects are somehow not a valid input for this array-based method. If this is the case, are there W3C standards-compliant ways to get around this?

1
  • I'm afraid you actually accepted a wrong answer. If a variable is not declared locally, it will be a global variable by JS interpreter. The real problem is that you try to print an object before it is being added to nodes. Please check my solution below. Commented Jun 30, 2016 at 3:55

3 Answers 3

3

You attempt to print the index before the node is being added to nodes. You will always get -1. In short, please move DrawNode out of SeedNode.

function GenNodes() {
    for (var i=0; i<10; i++) {
        var node = new SeedNode()
        nodes.push(node)
        DrawNode(node,node.x,node.y)
    }
}

function SeedNode() {
    var node = {}
    node.shape = "circle"
    node.radius = "10"
    node.x = 730*Math.random() + 10
    node.y = 730*Math.random() + 10 
    return node 
} 
Sign up to request clarification or add additional context in comments.

2 Comments

I agree that this is the actual solution, but not just because he attempts to print the index before it's added to nodes. He also calls indexOf() here: seeds.fillText(nodes.indexOf(node),x_cen,y_cen).
Yes. I originally noticed my nodes were all being labeled as "-1" so I inserted another indexOf() method call into the function to confirm it was purely a javascript problem and not something super-weird in canvas. Hence the double-error!
2

Not tested but he problem seems to lie through out these three functions

function GenNodes() {
        // Rest of code
    nodes[i]= new SeedNode()
}

function SeedNode() {
        //Rest of code
        DrawNode(this,this.x,this.y)
} 

function DrawNode(node,x_cen,y_cen) {

    // Rest of code
    console.log(nodes.indexOf(node))
    seeds.fillText(nodes.indexOf(node),x_cen,y_cen)
}

In function GenNodes you are try to populate the the nodes array But this will depend on return from SeedNode function. Again this SeenNode is dependent on return from of DrawNode function . That mean once DrawNode & SeedNode have executed then it will put the element in the nodes array. But before putting the element you are checking the indexOf the element in nodes array inside DrawNode.

So it is returning -1 which I think is right according to this documentation on indexOf

1 Comment

Nice catch! It didn't even occur to me that I might be prematurely calling the method, but in fact everything is normal when I make a dedicated labeling function AFTER the nodes are created. Thanks :-)
2

You have a scoping problem. nodes is never declared anywhere that DrawNode() can find it. To fix it, declare nodes outside any function:

var testMe = [];
function doSomething() {
  doTheThing();
}

function doTheThing() {
  testMe[0] = "hi";
  testMe[1] = "there";
  doTheOtherThing();
}

function doTheOtherThing() {
  console.log("This works");
  console.log(testMe.indexOf("there"));
}

doSomething();

2 Comments

@stanleyxu2005 is correct and his solution is the right one.
Thanks for your honesty. In hindsight, my error was quite obvious, so I didn't actually check your specific code!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.