After exploring various options for similarities, like the one found here, I have not been able to find a solution to my particular issue.
The situation at hand involves a component consisting of organizations with labels and checkboxes attached to a v-model. This component will be utilized in conjunction with other form components. Currently, it is functioning correctly, but it only returns one value to the parent even when both checkboxes are clicked.
Form page:
<template>
<section>
<h1>Hello</h1>
<list-orgs v-model="selectedOrgs"></list-orgs>
<button type="submit" v-on:click="submit">Submit</button>
</section>
</template>
<script>
// eslint-disable-next-line
import Database from '@/database.js'
import ListOrgs from '@/components/controls/list-orgs'
export default {
name: 'CreateDb',
data: function () {
return {
selectedOrgs: []
}
},
components: {
'list-orgs': ListOrgs,
},
methods: {
submit: function () {
console.log(this.$data)
}
}
}
</script>
Select Orgs Component
<template>
<ul>
<li v-for="org in orgs" :key="org.id">
<input type="checkbox" :value="org.id" name="selectedOrgs[]" v-on:input="$emit('input', $event.target.value)" />
{{org.name}}
</li>
</ul>
</template>
<script>
import {db} from '@/database'
export default {
name: 'ListOrgs',
data: () => {
return {
orgs: []
}
},
methods: {
populateOrgs: async function (vueObj) {
await db.orgs.toCollection().toArray(function (orgs) {
orgs.forEach(org => {
vueObj.$data.orgs.push(org)
})
})
}
},
mounted () {
this.populateOrgs(this)
}
}
</script>
There are currently two mock organizations in the database with IDs 1 and 2. Upon selecting both checkboxes and submitting, the selectedOrgs array only contains 2 as if the second click replaced the first. Testing by checking only one box reveals that either 1 or 2 gets passed. It appears that the array method functions at the component level but not at the component-to-parent level.
Any assistance would be greatly appreciated.
UPDATE
Upon following the advice from puelo's comment, I modified my orgListing component to emit the array linked to the v-model like so:
export default {
name: 'ListOrgs',
data: () => {
return {
orgs: [],
selectedOrgs: []
}
},
methods: {
populateOrgs: async function (vueObj) {
await db.orgs.toCollection().toArray(function (orgs) {
orgs.forEach(org => {
vueObj.$data.orgs.push(org)
})
})
},
updateOrgs: function () {
this.$emit('updateOrgs', this.$data.selectedOrgs)
}
},
mounted () {
this.populateOrgs(this)
}
}
At the receiving end, I am simply performing a console log on the returned value. Though this "works," one drawback is that the $emit seems to trigger before the selectedOrgs value has been updated, resulting in it always being one step behind. Ideally, I want the emit to wait until the $data object has been fully updated. Is there a way to achieve this?