0

I have an object that contains pairs of data that I would like to display based on category. I believe this has to do with nested v-for loops, but I'm having trouble figuring out the right way to go about this.

 categoryArray = {stage 1, red}, {stage 1, blue}, {stage 2, orange}, {stage 3, brown}, {stage 2, green}

Desired display: Stage 1: red, blue Stage 2: orange Stage 3: brown

I do not have workable code yet. My strategy has been to create an array of unique Stages, use that to display the Stages, but I can't figure out how to iterate the items within the stages.

Getting the stages:

let stagesArray = [];
      categoryArray.value.forEach((entry, index) => {
        stagesArray.push(entry.stageNumber);
      });
      //creating array of unique stages

      uniqueRooms.value = [...new Set(stagesArray)];
    })

The above works to get the unique array of rooms.

<template>
   <div v-for="(stage, index) in uniqueRooms" :key="index">
       {{ room }}
      <div v-for="(color, index) in filterStages" :key="index">
         {{ color }} 
      </div>
   </div>
</template>
<script>

//this is a mess and I don't know where to go.
const filterStages = computed(function (stage) {
  return stagesUnique.value.forEach((stageNumber) => {
    return categoriesArray.value.filter((color) => color.stage     
    === stageNumber);
    
  });
 </script>

I am out over my skiis. I just need some leads on how to loop through the main category(stage), with unique values, and then display all matching colors within that category.

This seems very close, but I can't figure out the way to get unique stages from this. Nested loop in Vue

jdost_26
  • 371
  • 1
  • 14

2 Answers2

1

Is this what you're looking for?

const { createApp, computed } = Vue;

createApp({
  setup() {
    const data = [
      { stage: 1, color: 'red' },
      { stage: 1, color: 'blue' },
      { stage: 2, color: 'orange' },
      { stage: 3, color: 'brown' },
      { stage: 2, color: 'green' }
    ];
    const stages = computed(
      () => [...new Set(data.map(({ stage }) => stage))]
    );
    const stageColors = computed(
      () => s => data.filter(({ stage }) => stage === s)
                     .map(({ color }) => color)
    );
    return {
      stages,
      stageColors
    }
  }
}).mount('#app');
h4 { margin-bottom: 0;}
<script src="https://unpkg.com/vue@next/dist/vue.global.prod.js"></script>
<div id="app">
  <div v-for="stage in stages" :key="stage">
    <h4>Stage #{{ stage }}</h4>
    <ul>
      <li v-for="color in stageColors(stage)" :key="color" v-text="color" />
    </ul>
    <hr>
  </div>
</div>
tao
  • 82,996
  • 16
  • 114
  • 150
  • Wow! It worked. Thank you very much. Was feeling helpless. To narrate the solution, the computed function stages creates a new array from the unique values of the variable stages. Then the computed function stageColors creates new arrays for the colors in each array. Then this info is displayed in the template calling the stageColors function by the specific stage... Is that roughly correct? – jdost_26 Nov 23 '21 at 02:35
  • `stages` returns unique stages (array of numbers). `stageColors` returns a function, because it's a computed (getter) and therefore doesn't take params. If you find that confusing, you can write it as a method. This method (the returned function) takes in a stage, filters data entries by that stage and maps their colors. If you only want the unique colors (assuming at some point you'll have some repeated), you have to wrap the entire array returned into a `[...new Set()]`. – tao Nov 23 '21 at 03:07
0

You have the same index for both loops, so it's wrong

   <div v-for="(stage, index) in uniqueRooms" :key="index">
                                                     ----
       {{ room }}
      <div v-for="(color, index) in filterStages" :key="index">
                                                        -----
vueAng
  • 415
  • 2
  • 7