0

I'm working on creating a table that features a kebab menu in each row. When you click the 'Update' button, a dialog box opens, displaying the data from the current row. However, for some reason that I can't understand (Maybe something related to the refs) the data always corresponds to the last row. This issue persists even when I create a new row. When I click 'Update' on any other row, it still attempts to update the most recently added row(that is the last one in the table), and I don't understand why."

Here is the code:

<template>
  <div class="purposes">
    <h1>This is the Purposes page</h1>
    <Button label="Create" icon="pi pi-plus" @click="openDialog(null)"></Button>
    <Dialog v-model:visible="showDialog" modal header="Header">
      <template #header>
        <h2 v-if="isUpdateMode">Update Purpose</h2>
        <h2 v-else>Create Purpose</h2>
      </template>
      <InputText v-model="currentPurpose.name" placeholder="Name" />
      <InputText v-model="currentPurpose.key" placeholder="Key" />
      <InputText v-model="currentPurpose.terms" placeholder="Terms" />
      <Button
        v-if="isUpdateMode"
        label="Update"
        icon="pi pi-refresh"
        @click="updatePurpose"
      ></Button>
      <Button v-else label="Save" icon="pi pi-check" @click="createPurpose"></Button>
    </Dialog>
    <Card class="rounded-card">
      <template #content>
        <DataTable :value="purposes">
          <Column field="id" header="ID"></Column>
          <Column field="name" header="Name"></Column>
          <Column field="key" header="Key"></Column>
          <Column field="terms" header="Terms"></Column>
          <Column>
            <template #body="slotProps">
              <Button
                icon="pi pi-ellipsis-v"
                class="p-button-rounded p-button-text"
                @click="menu.toggle($event, slotProps.data)"
              ></Button>
              <Menu :model="menuItems(slotProps.data)" ref="menu" popup />
            </template>
          </Column>
        </DataTable>
      </template>
    </Card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { Purpose, CreateOrUpdatePurpose } from '@/types/global'
import {
  fetchPurposes,
  createOrUpdatePurpose as createOrUpdatePurposeAPI
} from '@/api/purposesService'

const purposes = ref<Purpose[]>([])
const menu = ref<any>(null)
const showDialog = ref(false)
const currentPurpose = ref<CreateOrUpdatePurpose>({
  id: null,
  name: '',
  key: '',
  terms: ''
})
const isUpdateMode = ref(false)

const menuItems = (purpose: Purpose) => [
  {
    label: 'Update',
    icon: 'pi pi-refresh',
    command: () => {
      console.log('Clicked update for: ', purpose) // Log here
      openDialog(purpose)
    }
  }
]

onMounted(async () => {
  try {
    const data = await fetchPurposes()
    if (data) {
      purposes.value = data
    }
  } catch (error) {
    console.error('An error occurred while fetching purposes:', error)
  }
})

const openDialog = (purpose: Purpose | null) => {
  console.log('Purpose in openDialog: ', purpose) // Log here
  if (purpose) {
    isUpdateMode.value = true
    currentPurpose.value = { ...purpose }
  } else {
    isUpdateMode.value = false
    currentPurpose.value = { name: '', key: '', terms: '' }
  }
  console.log('CurrentPurpose after update: ', currentPurpose.value) // Log here
  console.log('Is update mode: ', isUpdateMode.value) // Log here
  showDialog.value = true
}

const createPurpose = async () => {
  try {
    const createdPurpose = await createOrUpdatePurposeAPI(currentPurpose.value)
    purposes.value.push(createdPurpose)
    showDialog.value = false
  } catch (error) {
    console.error('An error occurred while creating the purpose:', error)
  }
}

const updatePurpose = async () => {
  try {
    const updatedPurpose = await createOrUpdatePurposeAPI(currentPurpose.value)
    const index = purposes.value.findIndex((p) => p.id === updatedPurpose.id)
    if (index !== -1) {
      purposes.value[index] = updatedPurpose
    }
    showDialog.value = false
  } catch (error) {
    console.error('An error occurred while updating the purpose:', error)
  }
}

The console.log at menuItems have already the wrong purpose in it. Thanks!

1 Answer 1

0

on the button instead of the @click="menu.toggle($event, slotProps.data)" put console.log(slotProps.data) and check if the result still be the last row data or not.

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.