0

I am attempting to set up a map method in JavaScript and Vue that creates a new array of objects while returning only selected items in each object. To accomplish this, I set up a UI with 2 checkboxes corresponding to 2 separate objects:

    <div v-for="object in objects" :key="object.id" class="max-w-sm rounded overflow-hidden shadow-lg justify-center">
      <div class="px-6 py-4">
        <div class="font-bold text-xl mb-2">{{ object.name }}</div>
      </div>
      <span class="flex-1 flex mt-8 m-2">
        <span class="flex flex-col">
          <input v-model="checkBoxArray" :value="object.id" @click="selectObject(object.id)" type="checkbox" class="h-5 w-5" />
        </span>
      </span>
    </div>
  const objects = [
  {
    id: 1,
    name: 'bucky barnes',
    title: 'winter soldier',
    cellnum: '123-456-7890',
    email: '[email protected]',
    description: 'Description 1'
  },
  {
    id: 2,
    name: 'sam wilson',
    title: 'falcon',
    cellnum: '098-765-4321',
    email: '[email protected]',
    description: 'Description 2'
  },
]

The selectObject handler on the checkbox input pushes the id of a selected object to checkBoxArray:

const checkBoxArray = ref([])

const selectObject = (id) => {
  checkBoxArray.value.push(id)
}

Then, a watch property is used to watch for changes to checkBoxArray.value, then call a function that uses map to create a new array targeting the id of the selected object:

watch(checkBoxArray.value, () => {
  const storedObjects = objects.map(val => checkBoxArray.value.find(obj => obj === val.id), ['id', 'name', 'title'])
  console.log(storedObjects)
})

My expectation is the new array created will be an array with an object containing ONLY the id, name, and title from the original object. example:

{id: 1, name: 'bucky barnes', title: 'winter soldier'}

However, I currently only returning a new array with the id of the selected object. How can I go about setting up the map and find methods in the watch property to create a new array with an object containing ONLY id, name, and title?

Here is the full code:

<template>
  <div>
    <div v-for="object in objects" :key="object.id" class="max-w-sm rounded overflow-hidden shadow-lg justify-center">
      <div class="px-6 py-4">
        <div class="font-bold text-xl mb-2">{{ object.name }}</div>
      </div>
      <span class="flex-1 flex mt-8 m-2">
        <span class="flex flex-col">
          <input v-model="checkBoxArray" :value="object.id" @click="selectObject(object.id)" type="checkbox" class="h-5 w-5" />
        </span>
      </span>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watch } from 'vue';

  const objects = [
  {
    id: 1,
    name: 'bucky barnes',
    title: 'winter soldier',
    cellnum: '123-456-7890',
    email: '[email protected]',
    description: 'Description 1'
  },
  {
    id: 2,
    name: 'sam wilson',
    title: 'falcon',
    cellnum: '098-765-4321',
    email: '[email protected]',
    description: 'Description 2'
  },
]

const checkBoxArray = ref([])

const selectObject = (id) => {
  checkBoxArray.value.push(id)
}

watch(checkBoxArray.value, () => {
  const storedObjects = objects.map(val => checkBoxArray.value.find(obj => obj === val.id), ['id', 'name', 'title'])
  console.log(storedObjects)
})

onMounted(() => {
  console.log(objects)
})
</script>

1 Answer 1

2

There is no syntax of map function that filters the fields by 2nd argument:

                                                             // This parameter will not work
                                                                          👇
objects.map(val => checkBoxArray.value.find(obj => obj === val.id), ['id', 'name', 'title'])

You should filter the objects that are stored first, then use map to transform them:

const storedObjects = objects
.filter(obj => checkBoxArray.value.find(id => id === obj.id)) // this returns the array of object that are stored
.map(elm => {
 return {
   id: elm.id,
   title: elm.title,
   name: elm.name
 }
})
Sign up to request clarification or add additional context in comments.

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.