1

I have the following Foods Object:

var Foods = {
  "Fruits": [{
   "id": "1",
   "Name": "Granny Smith",
   "Category": "1"
  }, {
   "id": "2",
   "Name": "Raspberries",
   "Category": "1"
   }
],
 "Potatoes": [{
   "id": "3",
   "Name": "Maris Piper",
   "Category": "2"
  }, {
   "id": "4",
   "Name": "Charlotte",
   "Category": "2"
 }]
 }

What I would like to do is only push the produce that matches an id passed by a link.

<a href="javascript:void(0)" class="cat" id="2" onClick="getCat(this.id)">Get Foods</a>

This is what I have tried so far:

function getCat (id){
 result = [];
 for(let item in Foods) {
    if(Foods[item].id == id) {
        data[item].foreach(v=>result.push("<div class='box'><h2>" + 
        data[key].Name + "<br></div>"));
    }
  }
}

display();

function display() {
  alert(result);
}

So if a user hits the link (which has an id of 2), the result array should contain "Charlotte" and "Maris Piper" but I am just drawing a blank.

Any help appreciated.

Cheers

4
  • what is your variable result = []; scope? is it a global scope? Commented Jul 27, 2017 at 9:10
  • Whats data ???? And js is typesafe, so its onclick and forEach Commented Jul 27, 2017 at 9:10
  • Sorry should be a Foods object. Commented Jul 27, 2017 at 9:13
  • I think you might be looking for array.filter, but it is completely unclear what your data looks like and what you want to get out of it. Commented Jul 27, 2017 at 9:13

4 Answers 4

5

Youre quite close, however theres a slight problem:

for(let item in Foods) {
  console.log(Foods[item]);
  /*
  [{
  "id": "1",
  "Name": "Granny Smith",
 "Category": "1"
   }, {
   "id": "2",
   "Name": "Raspberries",
   "Category": "1"
   }
]
*/

So youre iterating over the categories, which are arrays.

Foods[item].id

is undefined as its an array and not a product. So we need to iterate the array to, e.g.

var result=[];
Object.values(Foods).forEach(function(category){
 category.forEach(function(product){
   if(product.id===id){
     result.push(product);
   }
 });
});

Run

But if youre doing this quite often, it might be easier to create one product array once:

var products = Object.values(Foods).reduce((arr,cat)=>arr.concat(cat),[]);

So you can simply filter this whenever someone clicks a button:

var result = products.filter(product=>product.id === id);

Run

Sign up to request clarification or add additional context in comments.

10 Comments

Did you mean to write var category in Foods instead of of Foods since of doesn't work on Objects.
@antonio smoljan of doesnt work on objects lol. everything in js is an object.
You are certainly right it is but, the for..of loop only supports iterable objects like arrays, not objects.
@antonio smoljan lol, always have used it like this, never noticed that it doesnt work :/ . thanks ;)
No problem great answer im upvoting it, just wanted to see if i was mistaken :)
|
1

You're somewhat on the right track, but what's data? Why are you not doing anything with result? And you should be looking at the Category property rather than ID.

This'll work:

function getCat(id) {
    let result = [];

    for (let item in Foods) {
        if (Foods.hasOwnProperty(item)) {
            Foods[item].forEach((food) => {
                if (food.Category == id) {
                    result.push(food);
                }
            });
        }
    }

    console.log(result);
}

3 Comments

Thanks for your help. Tried your solution and if I do document.write(result) it returns [object Object],[object Object]
@hexana yes its an object. 1) dont use document.write 2) simply build up a string like you already did in your code instead
Jonas do you have an example as I can't seem to get it to work?
0

First of all result array should be at global scope so that you can access it in another function, And in object you are having categories then each category has some data in array so after iterating over object, you need to iterate the items from array as well to get the value. Check the below code.

var result = [];
    function getCat(id){
     for(let item in Foods) {
        var foodItem = Foods[item];
        for(let i=0; i<foodItem.length; i++){
           if(foodItem[i].id == id) {
              result.push("<div class='box'><h2>" + foodItem[i].Name + "<br></div>"));
           } 
        }

      }
    }

function display() {
  alert(result);
}

display();

Comments

0

Iterator is wrong. You should do it like this:

function getCat(id){
    result = [];
    for(let item in Foods) {
        Foods[item].forEach(function(each){
            if(each.id == id) { // you cmpare to the wrong target
                // do something
            }
        });
    }
}

Comments

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.