Search code examples
javascriptvue.jscomponentsreduce

How to use reduce to pass information to a base component? / Getting correct data passed with computed props in VueJS


I'm currently working on an inventorying app and I am trying to display the boxID and the amount of items inside of that box on a baseCard component that I have made.

The computed property that I made boxCards needs to spit the data out in this format [{title: '', amount: null}] so it can be pushed onto each baseCard element.

Presently my computed property is giving me the title, but I cannot figure out how to get the amount of items inside of each box.

boxesInLocation returns this array: ["", "Box 1", "Box 4", "Box 4"]

Which is great, but now I need to count how many times each box shows up in that area and then push it to the reshapedItems function in the amount: spot.

Is this just a simple reduce method that I need to use? Because I've only be able to actually produce a number when calculating the length of the array.

Also, just reducing the array won't spit out the number to each individual instance of reshapedItem

Any ideas on what I can do here?

Cheers!

App.Vue Data:

data(){
    userData: {
        items: [
          {
            itemName: 'test book',
            category: 'Books',
            box: 'Box 3',
            location: 'Kitchen',
          },
          {
            itemName: 'test book 2',
            category: 'Books',
            box: 'Box 3',
            location: 'Kitchen',
          },
          {
            itemName: 'test book 3',
            category: 'Books',
            box: '',
            location: 'Basement',
          },
          {
            itemName: 'test record',
            category: 'Records',
            box: 'Box 1',
            location: 'Basement',
          },
          {
            itemName: 'test record 2',
            category: 'Records',
            box: 'Box 4',
            location: 'Basement',
          },
          {
            itemName: 'test furniture',
            category: 'Furniture',
            box: 'Box 2',
            location: 'Garage',
          },
          {
            itemName: 'test movie 1',
            category: 'Movies',
            box: 'Box 2',
            location: 'Garage',
          },
          {
            itemName: 'test movie 2',
            category: 'Movies',
            box: 'Box 2',
            location: 'Garage',
          },
          {
            itemName: 'test movie 3',
            category: 'Movies',
            box: 'Box 2',
            location: 'Garage',
          },
          {
            itemName: 'test Comicbook',
            category: 'Movies',
            box: 'Box 4',
            location: 'Basement',
          },
        ],
        boxes: [
          { name: 'Box 1', location: 'Basement' },
          { name: 'Box 2', location: 'Garage' },
          { name: 'Box 3', location: 'Kitchen' },
          { name: 'Box 4', location: 'Basement' },
        ],
   }

Page Component

  data() {
    return {
      items: this.userData.items,
      boxes: this.userData.boxes,
    }
  },
  computed: {
    boxCards() {
      const filteredItems = this.items.filter((item) => item.location === 'Basement')
      const itemsInBoxes = filteredItems.map((filteredItem) => {
        return filteredItem.box
      })

      const filteredBoxes = this.boxes.filter((box) => box.location === 'Basement')

      const reshapedBoxes = filteredBoxes.map((filteredBox) => {
        return { boxID: `${filteredBox.name}`, amount: 100 }
      })
      return reshapedBoxes
    },

Solution

  • You can count the items in the this.items array that have the same box name as the box in question:

    return this.boxes
      .filter((box) => box.location === 'Basement')
      .map((box) => ({
        boxId: `${box.name}`,
        amount: this.items.filter(item => item.box === box.name).length
      }));