-1

I'm fairly certain this is a simple mistake, but I'm confused as to why this won't work. I've been unable to find any documentation on using multiple brackets in a row when accessing properties. This is part of my code that creates a link that when clicked runs the "dropItem" function:

var dropDest = "screwdriver";
var dropCat = "supplies.tools";
dropButton.onclick= function() {dropItem(dropCat, dropDest)};

The "dropItem" function:

var dropItem = function(category, droppedItem) {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1; }; 

I get a "Cannot read property 'screwdriver' of undefined" error. How would one properly pass this? Both properties need to be variables for it to work. Is this an error due to multiple brackets?

EDIT:

I realized I forgot to include how the player object is structured, and this is critical for understanding why I needed to pass a dot-notated category:

var player = {
  "health": 100,
  "hydration": 100,
  "hunger": 100,
  "energy": 100,

  "inventory": {
      "supplies": {
          "tools": {
            "screwdriver": {
                "amount": 0,
                "condition": 0
            }
          },
          "buldingMaterials": {
            "wood": {
                "amount": 0,
                "condition": 0
            }
          }
      },          
      "aidPacks": {
          "healthPacks": 0
      }
  }
}

This is why I need to be able to access both player.inventory.supplies.tools and player.inventory.aidPacks.healthpacks with the same function.

RGStrat
  • 25
  • 7

3 Answers3

1

After looking at lightstalker89's code I realized that my issue was not the brackets, but rather the category that was being passed was not parsing the dot notation in the middle, thus staying as "supplies.tools" instead of separating fully. However, due to the way the player object is structured I needed to be able to pass dot notated categories, so I split the string:

var player = { "inventory": { "supplies": { "tools" : { "screwdriver" : { "amount" : 1}}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";

function dropItem(category, droppedItem) {
   if(category.indexOf(".") > 0) {
       var newCat = category.split(".");
       var cat1 = newCat[0];
       var cat2 = newCat[1];
       player.inventory[cat1][cat2][droppedItem].amount = player.inventory[cat1][cat2][droppedItem].amount - 1;
       alert(player.inventory[cat1][cat2][droppedItem].amount);
   }else {
       player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
       alert(player.inventory[category][droppedItem].amount);
   }
}
dropItem(dropCat, dropDest);

Here's the JSFiddle: https://jsfiddle.net/j7g0d8kz/

Again, huge thanks to @lightstalker89 for making me realise my mistake.

RGStrat
  • 25
  • 7
1

You can make your code more generic and easier. This is useful when you have more than two categories - then you dont need to work with [0] and 1 - here is the code:

var player = { "inventory": { "supplies": { "tools" : { "screwdriver" : { "amount" : 1}}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";

function getProperty(obj, str) {
    return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}

function dropItem(category, droppedItem) {
   var accessString = dropCat + "." + droppedItem;
   getProperty(player.inventory, accessString).amount -= 1;         
   alert(getProperty(player.inventory, accessString).amount);
}
dropItem(dropCat, dropDest);

Here is the fiddle: https://jsfiddle.net/j7g0d8kz/3/

Mario Murrent
  • 712
  • 5
  • 24
0

How does your player object look like? Is it an empty object when you want to change the properties.

Basically you can use multiple brackets as you did.

If the player object does not have the needed properties, then your code should look like this:

var player = {};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
    if(!player.inventory){
        player.inventory = {};
    }
    if(!player.inventory[category]){
        player.inventory[category] = {};
    }
    if(!player.inventory[category][droppedItem]){
       player.inventory[category][droppedItem] = { amount: 0};
    }
    player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;       
}
dropItem(dropCat, dropDest);
alert(JSON.stringify(player));
alert(player.inventory[dropCat][dropDest].amount);

Here is the fiddle: https://jsfiddle.net/csqbjnd7/1/

If the player object exists you can use multiple brackets. The code should then look like this:

var player = { "inventory": { "supplies.tools" : { "screwdriver" : { "amount" : 1}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
   player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
}
dropItem(dropCat, dropDest);
alert(player.inventory[dropCat][dropDest].amount);
alert(JSON.stringify(player));

Here is the fiddle: https://jsfiddle.net/9o1949oz/2/

Mario Murrent
  • 712
  • 5
  • 24
  • Sorry for the delay, I was trying to figure out how that second code was working since it was so close to mine. I figured out that it's because my player object is structured as 'player.inventory.supplies.tools.screwdriver.amount' This is because there are multiple types of supplies, and multiple items other than supplies for example 'player.inventory.aidPacks.firstAid'. I think it's that dot that's being transferred that's causing me the issues. Perhaps because it is a string it will not properly access the properties? – RGStrat Aug 28 '15 at 18:25
  • Maybe this could be the case yes. If you want, just update your code, if the problem is not solved yet. – Mario Murrent Aug 28 '15 at 18:38
  • 1
    Thanks, lightstalker89. I figured it out finally. This was great since I've had this issue before. Thanks a million! – RGStrat Aug 28 '15 at 18:49
  • You're welcome. I'm glad that i could help you. Maybe you can mark an answer as accepted if it helped you :) – Mario Murrent Aug 31 '15 at 17:27