Search code examples
javascriptobjectjavascript-objects

Can’t access object key inside object function?


I am building a web app text based RPG game. The game will use textNodes and move to the next “question” after each answer is chosen from a question.

In my game, I will allow the user to select perks at the start of the game.

One of these perks is “greaser”.

There are factions in this game, and I want to check if the player has a greaser perk and also check to see if that question that is currently being asked contains the faction “greaser”.

If both of these things are true, I will run the same logic, but with reduced damage. If not, I’ll just run the function as it appears.

Here is the code for 2 questions, one of which has a function.

function addRadiatedStatus() {
  character.radiated = true;
}

const textNodes = [
  {
    id: 1,
    text: "Do you want to help this person?",
    options: [
      {
        text: "Yes",
        nextText: 2,
      },
      {
        text: "No",
        nextText: 2,
      },
    ],
    faction: "Greaser",
  },
  {
    id: 2,
    text: "It was a trap, do you run or kill them?",
    options: [
      {
        text: "Run",
        nextText: 3,
        damage: 0,
      },
      {
        text: "Kill",
        nextText: 5,
        damage: 8,
        moneyDrop: 20,
        radiationDamage: 2,
        function: function update() {
          if (character.greaser == true && textNodes[1].faction == "greaser") {
            console.log("greaser check worked");
          }
          console.log("upadte function worked");
          character.health -= this.damage;
          character.cash += this.moneyDrop;
          character.radiationLevel += this.radiationDamage;
          character.maxHP -= this.radiationDamage;
          if (this.radiationDamage >= 1) {
            addRadiatedStatus();
          }
          console.log("character HP" + " " + character.health);
          console.log("character maxHP" + " " + character.maxHP);
          console.log("moneyDrop " + " " + this.moneyDrop);
          console.log("character cash" + " " + character.cash);
          console.log("radiation level" + " " + character.radiationLevel);
          console.log("character Raditated?" + " " + character.radiated);
        },
      },
    ],
    faction: "Greaser",
  },
];

textNodes[1].options[1].function();

As you can see, I am hard coding textNodes[1].faction, which will become very annoying once I have hundreds of questions/choices.

I am looking for a way to say something like `textNodes[textNodes.id].faction’, allowing me t reuse code and no have to hard code.

I am also confused on how I can also automatically call any function within a question choice/answer , because currently, I am hard coding the fucntion call at the bottom of my page like this textNodes[1].options[1].function().

I want to be able todo 2 things...

  1. Call that function automatically whenever the choice is chosen by the player

  2. Dynamically add the textNode ID to the if/else check for “greaser”.

I am new to javascript and I am not sure why I am having trouble obtaining the Key “id” from within my function.

Thanks in advance.


Solution

  • Change your callback function declaration. You are using:

    function: function update(){
    

    and to call it you use:

    textNodes[1].options[1].function();
    

    Instead you could write it like this:

    update: () => { 
    

    and call it like this:

    textNodes[1].options[1].update();
    

    Additionally if you don't want to hard code anything you could change the character object and instead of boolean character.greaser you could create string character.faction having value greaser, then you could simply do this

    if (character.faction == this.faction) {
          console.log("greaser check worked");
    }
    

    You could also try to pass the id as an argument of the update() function.

    update: (id) => { // pass id in update function
    
    if (character.faction == textNodes[id].faction) { // check is done
          console.log("greaser check worked");
    }
    
    textNodes[1].options[1].update(1); //  this could help in case you want to also check values of other textNodes