-
Notifications
You must be signed in to change notification settings - Fork 700
UTable #actions-data outdated when rows change #2004
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello. I try and its work for me <script setup>
import { PostsModal } from '#components';
const modal = useModal()
const posts = ref([
{
id: 1,
title: 'Title1'
},
{
id: 2,
title: 'Title2'
},
{
id: 3,
title: 'Title3'
}
])
const columns = [
{
key: 'id',
label: 'ID',
},
{
key: 'title',
label: 'Title',
},
{
key: 'actions',
label: 'Actions',
},
];
function rename(post) {
console.log(post)
modal.open(PostsModal, {
id: post.id,
oldTitle: post.title,
onConfirmRename(newTitle) {
console.log(newTitle)
posts.value.forEach(elem => {
if (elem.id === post.id) {
return elem.title = newTitle
}
});
modal.close()
},
onCancel() {
modal.close()
}
})
}
</script>
<template>
<UTable :columns="columns" :rows="posts">
<template #actions-data="{ row }">
<UButton title="Rename" color="primary" @click="rename(row)">Rename</UButton>
</template>
</UTable>
</template> <script setup>
const emit = defineEmits(['confirmRename', 'cancel'])
const props = defineProps({
id: Number,
oldTitle: String,
})
const newTitle = ref(props.oldTitle)
</script>
<template>
<UModal>
<UCard>
<p>
New name for post with title <span> {{ oldTitle }} </span> is:
</p>
<input v-model="newTitle" placeholder="New title" />
<template #footer>
<div>
<UButton variant="ghost" @click="emit('cancel')">Cancel</UButton>
<UButton color="primary" @click="emit('confirmRename', newTitle)">Rename</UButton>
</div>
</template>
</UCard>
</UModal>
</template> |
True. I forked a Stackblitz with your code: https://stackblitz.com/edit/github-hpn25g-femxdi Yes it is working. Played around a bit and the reason/difference is, that you manipulate the data array (posts) in place instead of replacing the whole array. That is interesting, but not really a solution since in a real-world scenario we use the "refresh" function of AsyncData. So why does the table component have a problem with replacing the whole data array? |
this works fine https://stackblitz.com/edit/github-hpn25g-oehbpx i change this func async function postsRefresh(updatedPost) {
posts.value = posts.value.map((item) => {
if (item.id === updatedPost.id) {
return updatedPost;
}
return item;
});
} to this function postsRefresh(updatedPost) {
posts.value.forEach((post) => {
if (updatedPost.id === post.id) {
post.title = updatedPost.title
}
})
} maybe problem in your composable func |
@ldiellyoungl I already got the difference when you answered the first time. It is not a fix to the problem since you are talking about code which we do not have in production scenario. The StackBlitz is only for demonstration purposes. In reality we do not have such a The real bug is that after replacing the data array the table does reflect the new model properties, so the rendering is correct. But what is not correct is the model data which is passed to actions ("#actions-data"). |
hmmm... maybe i dont understand, sorry. In my production i use websockets and change array with forEach method |
No worries. Using foreach and keeping the existing items list is also some kind of workaround for this problem described here (could be problematic if there are new or removed items from the list though?). We work around the issue like initially mentioned: we just ignore the model data which goes into #actions-data and find the model by id from the data array which is always uptodate. |
I experement with your code async function postsRefresh(updatedPost) {
posts.value = posts.value.map((item) => {
if (item.id === updatedPost.id) {
return updatedPost;
} else {
return item;
}
});
console.log(posts.value)
} first object is not proxy. maybe this is problem? async function postsRefresh(updatedPost) {
posts.value = posts.value.map((item) => {
if (item.id === updatedPost.id) {
return Object.assign(item, updatedPost);
} else {
return item;
}
});
console.log(posts.value)
} |
I have the same problem. As a side note |
I'm troubleshooting a problem caused by the PR for this issue and wanted to share a discovery in case someone else views this discussion. The refresh issue ironically has nothing to do with the table and is instead a side effect of the https://stackblitz.com/edit/github-hpn25g-uhp6qdgd?file=app.vue I added a second button within the actions template but outside of This demonstrates that the table and |
Environment
Version
v2.17.0
Reproduction
https://stackblitz.com/edit/github-hpn25g
Description
We recognized that the row data which is passed to "actions" does not reflect the state of the row data after the items array is replaced. This can happen when the whole list of items is refetched from a backend. It is relevant that the actions data is in sync with the rendered data since the actions themselves could also lead to other backend requests.
Repro:
I am aware that I have to "fake" the refetch mechanism since the used dummy API does not allow mutations on the server. In our real world scenario we have a real backend but the issue is still reproducible.
As a workaround we use a constant field of a model (e.g. "id") and grab the item from the refetched lists of models before we pass it to the modal.
Is this a real bug or are we doing something wrong here? If you could give me some hints where/how to start I could try to provide a PR with a fix.
Additional context
No response
Logs
No response
The text was updated successfully, but these errors were encountered: