0

I have a Vue page to display recipes by category:

<template>
  <div class="recipes-page">
    <div class="recipes" v-for="r in categoryRecipes" :key="r.id">
      <span>{{ r.title }}</span>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    loadedRecipes() {
      return this.$store.getters.loadedRecipes;
    },
    loadedCategories() {
      return this.$store.getters['categories/loadedCategories'];
    },
    categoryRecipes() {
      let categorized = [];
      this.$store.getters['categories/loadedCategories'].forEach(cat => {
        this.$store.getters.loadedRecipes.forEach(recipe => {
          if (cat.id in Object.keys(recipe.categories)) { // doesnt work
            console.log("Recipe has the category with id: " + cat.id);
            categorized.push(recipe);
          }
        });
      });
      return categorized;
    }
  }
};
</script>

In the data structure we have categories and recipes:

Categories:

[                                                                                                                                              
  {
    name: 'Juices',
    recipes: {
      '-L_Pg_BbwMYaGQjI2ejd': true
    },
    id: 'juices'
  },
  {
    name: 'Misc',
    recipes: {
      '-L_Pg_BbwMYaGQjI2ejd': true,
      '-L_PjcLaCvhZr9nb6wbh': true
    },
    id: 'misc'
  }
]

Recipes:

[                                                                                                                                              
  {
    author: 'Ian K',
    categories: {
      juices: true,
      misc: true
    },
    citation: 'none',
    cookTime: 'n/a',
    created: '2019-03-08T00:27:09.774Z',
    description: 'How to make Orange Juice from frozen concentrate.',
    directions: 'Mix frozen orange juice and water in a pitcher.',
    featured: true,
    id: '-L_Pg_BbwMYaGQjI2ejd',
    prepTime: '1 min',
    starCount: 5,
    thumbnail: 'https://baconmockup.com/420/420',
    title: 'Orange Juice from Concentrate',
    totalTime: '1 min',
    updated: '2019-03-08T00:27:09.774Z',
    yield: '8 Cups'
  },

  ...
]

The problem is that the if statement never returns true, even though the cat.id does exist in the recipe categories keys. Does anyone know why checking the keys array contents does not work?

I'd also like to know if chaining iteration like this will have a negative performance impact, and if there is a better/more convenient way to go about it?

4
  • Hard to say much since you haven't shown the data structure, but from the name, might it be that recipe.categories is an array and not an object? Commented Mar 12, 2019 at 19:17
  • What is cat.id value? Because Object.keys(recipe.categories) returns a list with strings but it looks like you would want to test the values Commented Mar 12, 2019 at 19:17
  • 1
    Did you try if (recipe.categories[cat.id]) { ... }. if the recipe id is property name for recipe.categories object, then this is the fastest way to do it, performance wise. Commented Mar 12, 2019 at 19:22
  • @Teddy's solution worked, although Stephen Thomas's answer works as well, the original question also asked how to make it perform better. I will post my new code with Teddy's solution as it seems to be the better answer. Commented Mar 12, 2019 at 19:53

2 Answers 2

1

Since Object.keys() returns an array, you probably want something like

if (Object.keys(recipe.categories).includes(cat.id)) {
Sign up to request clarification or add additional context in comments.

Comments

0

Use

if (recipe.categories[cat.id]) { 
  // ...
}

This is the fastest way as it doesn't iterate through each category for each recipe.

1 Comment

Works as long as recipe.categories[] isn't 0 or "", which is presumably a safe bet in this case.

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.