0

I'm trying to sort out my site's wishlist function and to do so I need to call a value from an array inside another array, I need to get the bottom level products object value, depending on which 4th level options object is needed (dependent on the 4th level id (44, 9, 8, 7, 6, 475 in this case)):

var jsonProductData = {
    "attributes" : {
        "133": {
            "id":"133",
            "code":"size",
            "label":"Size",
            "options": [
                {"id":"44","label":"XS","price":"0","oldPrice":"0","cssclass":"","products":["11921"]},
                {"id":"9","label":"S","price":"0","oldPrice":"0","cssclass":"","products":["11922"]},
                {"id":"8","label":"M","price":"0","oldPrice":"0","cssclass":"","products":["11923"]},
                {"id":"7","label":"L","price":"0","oldPrice":"0","cssclass":"","products":["11924"]},
                {"id":"6","label":"XL","price":"0","oldPrice":"0","cssclass":"","products":["11925"]},
                {"id":"475","label":"XXL","price":"0","oldPrice":"0","cssclass":"","products":["11926"]}
            ]
        }
    },
    "template" : "\u00a3#{price}",
    "basePrice" : "187",
    "oldPrice" : "299.99",
    "productId" : "11950",
    "chooseText" : "Select Size...",
    "taxConfig" : {
        "includeTax" : false,
        "showIncludeTax" : true,
        "showBothPrices" : false,
        "defaultTax" : 0,
        "currentTax" : 0,
        "inclTaxTitle" : "Inc VAT"
    }
};

Although there may be multiple 2nd level 'attribute' objects, so so far I have:

for (var key in jsonProductData['attributes']) {
    $j(jsonProductData.attributes[key].options.select(.id==7)
}

I know this isn't particularly far although I'm at a complete loss how to get past this, as the id I need to use is a value in an object, which doesn't seem to work with this select function.

Anyone able to help?

John Slegers
  • 45,213
  • 22
  • 199
  • 169
eddhall
  • 193
  • 17
  • There's a missing `)` somewhere in `$j(jsonProductData.attributes[key].options.select(.id==7)`. Also, what is `$j`? A library? – Jordan Gray Nov 08 '16 at 15:21
  • 1
    It's not JSON anymore by the time you're getting to that point: it's just an object. So access the data the same way you would any other object structure. If you had an array of objects (e.g., "options"), how would you get the element you want? [Find object by id in an array of JavaScript objects](http://stackoverflow.com/q/7364150/215552), perhaps. – Heretic Monkey Nov 08 '16 at 15:29
  • Hey Jordan, $j is for some reason our site's jquery. The function's no where near complete, so I was trying to work out what else I needed to add. – eddhall Nov 08 '16 at 15:47
  • Hey Mike, unfortunately javascript in general is far from my strength, I'll have a look at that link and see if I can figure it out – eddhall Nov 08 '16 at 15:49
  • Sorry can you give an example of an input and what should be the output? I am bit lost what are you trying to do here. – xszaboj Nov 08 '16 at 16:02
  • @Edward : The first thing you should do, is add proper intentation to your object, so you can actually read it (I did that for you). - Then, [**try to understand how to access properties of the object**](https://www.mkyong.com/javascript/how-to-access-json-object-in-javascript/). Once you figure that out, it should be a piece of cake, really... – John Slegers Nov 08 '16 at 16:03
  • Hey John, yes sorry about that, I understand how to access a specific property, but it's more accessing another property based on a value of a different property at the same 'level', so for example if I wanted to find the product id of id "44", where the result would be "11921" – eddhall Nov 08 '16 at 16:16

2 Answers2

0

This will get the id from inside the options array for each item:

var jsonProductData = {
    "attributes" : {
        "133": {
            "id":"133",
            "code":"size",
            "label":"Size",
            "options": [
                {"id":"44","label":"XS","price":"0","oldPrice":"0","cssclass":"","products":["11921"]},
                {"id":"9","label":"S","price":"0","oldPrice":"0","cssclass":"","products":["11922"]},
                {"id":"8","label":"M","price":"0","oldPrice":"0","cssclass":"","products":["11923"]},
                {"id":"7","label":"L","price":"0","oldPrice":"0","cssclass":"","products":["11924"]},
                {"id":"6","label":"XL","price":"0","oldPrice":"0","cssclass":"","products":["11925"]},
                {"id":"475","label":"XXL","price":"0","oldPrice":"0","cssclass":"","products":["11926"]}
            ]
        }
    },
    "template" : "\u00a3#{price}",
    "basePrice" : "187",
    "oldPrice" : "299.99",
    "productId" : "11950",
    "chooseText" : "Select Size...",
    "taxConfig" : { "includeTax":false,"showIncludeTax":true,"showBothPrices":false,"defaultTax":0,"currentTax":0,"inclTaxTitle":"Inc VAT" }
};
var idToLookFor = 7;
for (var key in jsonProductData.attributes) {
  var options = jsonProductData.attributes[key].options;
  for (var i=0; i < options.length; i++) {
    console.log('options[' + i + '].id = ' + options[i].id);
    var idAsInteger = parseInt(options[i].id);
    if (idToLookFor === idAsInteger) {
      var products = options[i].products;
      for (var j=0; j < products.length; j++) {
        console.log('   --> products[' + j + '] = ' + products[j]);
      }
    }
  }
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
  • Hey Peter, thanks for the reply, yes but then how do I get the 'products' object (and more importantly the associated 5 digit number) for a given id? – eddhall Nov 08 '16 at 16:13
  • Hey Peter, that's worked beautify, I'll definitely need to study it to see where I was going wrong as I could have sworn I had tried things like jsonProductData.attributes[key].options[0].products and nothing had returned! Thanks again – eddhall Nov 08 '16 at 16:36
  • Hey Peter, One more quick question, I'm using "var idToLookFor = $j("#attribute"+ key).val()" just after the start of the for section to get the selected attribute 'values' to search for. A console log shows that each value is correct at the start, but now the console log options[i].products returns undefined - if I manually assign the idToLookFor to the same value it returns the correct value, what could be going wrong? – eddhall Nov 08 '16 at 17:02
  • Calling val() returns a string, and then === will produce false. Make sure that on both sides of === the same type is used. Use parseInt() if necessary. – Peter B Nov 08 '16 at 17:11
0

You could get a list of those nested objects, and then find the one with a particular id as follows:

var jsonProductData={"attributes":{"133":{"id":"133","code":"size","label":"Size","options":[{"id":"44","label":"XS","price":"0","oldPrice":"0","cssclass":"","products":["11921"]},{"id":"9","label":"S","price":"0","oldPrice":"0","cssclass":"","products":["11922"]},{"id":"8","label":"M","price":"0","oldPrice":"0","cssclass":"","products":["11923"]},{"id":"7","label":"L","price":"0","oldPrice":"0","cssclass":"","products":["11924"]},{"id":"6","label":"XL","price":"0","oldPrice":"0","cssclass":"","products":["11925"]},{"id":"475","label":"XXL","price":"0","oldPrice":"0","cssclass":"","products":["11926"]}]}},"template":"\u00a3#{price}","basePrice":"187","oldPrice":"299.99","productId":"11950","chooseText":"Select Size...","taxConfig":{"includeTax":false,"showIncludeTax":true,"showBothPrices":false,"defaultTax":0,"currentTax":0,"inclTaxTitle":"Inc VAT"}};

var arr = Object.keys(jsonProductData['attributes']).reduce( function(acc, key, i, attr) {
    return acc.concat(jsonProductData['attributes'][key].options);
}, []);

// find obj with number 7:
var obj = arr.find(function (o) { return o.id == 7 });

// print it
console.log(obj);

// get product reference:
console.log('found product:', obj.products[0]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
trincot
  • 317,000
  • 35
  • 244
  • 286