Search code examples
javascriptjqueryeaseljscreatejs

JavaScript - extremely confused on removing elements from Container


I'm making a 2D, top-down Zelda style web rpg single player in JavaScript.

When the player (purple shirt) walks near a cat, it will "rescue" it... which basically removes the animalContainer from the ContainerOfAnimals (thereby removing animalContainer's BMP from the stage), and then add the id of that animalContainer to a rescuedTotal_Array...

The weird thing is, In the pic below, I'm able to rescue animalContainer2 and then rescue animalContainer1... But if I go from animalContainer1 to animalContainer2, it throws a

Uncaught TypeError: Cannot read property 'id' of undefined` error. 

... Basically:

Working way: get ID 22, then up to ID 21 ->>> One thing I notice with this is that the element name doesn't change for the ID... not sure why... so for the broken way... it may not be able to even associate element name animalContainer2 with an ID? But I don't know how the ID and the name could get disassociated like that..

ID in rescued array...: 22, element name: animalContainer1, rescued array length: 2, elem index pos: 0, index: 0

ID in rescued array...: 21, element name: animalContainer1, rescued array length: 2, elem index pos: 1, index: 0 

Broken way- throws error: get ID 21, then down to ID 22

ID in rescued array...: 21, element name: animalContainer1, rescued array length: 1, elem index pos: 0, index: 0 

1. Uncaught TypeError: Cannot read property 'id' of undefined 

enter image description here

Code Snippet:

        function grabIt(NPC_id, index) {
            //check if NPCid already exists in array before adding...
            if ($.inArray(ContainerOfAnimals.children[index].id, rescuedTotal_Array) == -1) {
                rescuedTotal_Array.push(ContainerOfAnimals.children[index].id);
            }
            if (rescuedTotal_Array.length == 2) {
                for (var z = 0; z < rescuedTotal_Array.length; z++) {
                    console.log("ID in rescued array...: " + rescuedTotal_Array[z] + ", \n element name: " + ContainerOfAnimals.children[index].name + ", rescued array length: " + rescuedTotal_Array.length + ",\n elem index pos: " + z + ",\n index: " + index);
                }
            }
            //when I remove the first added element to rescuedTotalArray... the 2nd element's index assumes first added element's index... (goes from 1 to 0)
            console.log(index);
            console.log("element removed: " + ContainerOfAnimals.children[index]);
            stage.update();
            ContainerOfAnimals.removeChild(ContainerOfAnimals.children[index]);
            updateHUD();
        }

I have no idea why the order in which I store elements in the array/remove them from the stage would matter...


EDIT: I feel I can solve this issue by removing element from ContainerOfAnimals by element ID instead of by index... by Container object offers no getChildID() function...

so I tried:

    var childToRemove = document.getElementById(ContainerOfAnimals.children[index]);
    console.log(childToRemove);
    ContainerOfAnimals.removeChild(childToRemove);

console.log(childToRemove) gives me null for children

But doing this: console.log(ContainerOfAnimals.children[index].id); gives me id 21, which is the correct id...


Solution

  • Beware that EaselJS elements aren't DOM elements.

    Supposing you want to remove an element by its id, I'd suggest this :

    function removeElementById(container, id) {
       for (var i=container.getNumChildren(); i-->0;) {
           if (container.getChildAt(i).id===id) {
                container.removeChildAt(i);
                return true;
           }
       }
       return false;
    }
    

    But using the id might not be the best architectural solution. In my EaselJS program I keep a reference to the objects themselves so that I don't have to search them.