Asynchronous update of property not being observed #9820
-
TL;DR: How to get a Vue3 Composition API application view to observe changes to asynchronously sourced updates to properties on an asynchronous sourced parent object? I have a backend services API layer for a blog post application that returns HAL JSON responses when querying for blog content. This allows the application to selectively, and progressively, retrieve only the information that's needed for any particular view. For example, when fetching all blog posts, you will receive an array response, with each element of the array being an object for each retrieved blog post, with the following (example) attributes: {
"_links": {
"self": {"href": "/blogs/112"},
"comments": {"href": "/comments?forBlog=112"},
"author": {"href": "/authors/56"}
},
"id": 112,
"title": "Using reactivity in Vue 3.",
"content": "It may be trickier than you might imagined.",
"created": "2023-12-12T11:16:31Z"
} In other front-end technologies (most notably AngularJS (v1)), I've dealt with this structure by instrumenting the individual blog post objects within the retrieved array. Each blog post is instrumented with Using the example JSON, say you're viewing a list of blog posts, and you're interested in the comments associated with a particular blog post (say, for blog post with AngularJS v1 appears to observe the change in the value of the property, and updates the view accordingly. I've tried a number of experiments in my Vue3 Composition API application, and I'm struggling to see how I can get a similar result with the Vue3 reactive system. I've read the Reactivity in Depth section of the documentation. And I've tried a few things. I do have the resolution of the Now, my thinking is that because the update of the property by the fetch is happening inside the (blog) object, then wrapping with a proxy ( What other techniques might help in this situation? Can you point me at alternative implementations that might work here? (It's probably worth pointing out that I don't have the option of major architectural changes to the services API.) Looking through this GitHub forum I saw this, and this, and perhaps especially this, which I think lean towards my thinking above. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
I don't quite understand your usage, perhaps you should try using 'ref' instead of reactive. Will not trigger a view update: <template>
<div v-for="blog in blogs" :key="blog.id">
{{ blog.title }}
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
let blogs = reactive([])
setTimeout(() => {
blogs = reactive([
{ id: 1, title: 'My first blog' },
{ id: 2, title: 'My second blog' },
{ id: 3, title: 'My third blog' },
])
// Will not trigger a view update
}, 1000)
</script>
View updates normally: <template>
<div v-for="blog in blogs" :key="blog.id">
{{ blog.title }}
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const blogs = ref([])
setTimeout(() => {
ref.value = [
{ id: 1, title: 'My first blog' },
{ id: 2, title: 'My second blog' },
{ id: 3, title: 'My third blog' },
]
// View updates normally.
}, 1000)
</script> I'm not sure if you are using it this way. Of course, if you could provide a minimal reproduction, I will be better able to address your issue. |
Beta Was this translation helpful? Give feedback.
-
When you say "make available later", what exactly do you do here? Where do you store the comments array? Vue's Reactivity relies in tracking property gets and sets. So the important part is that you read the actual property during the initial getter read, before the async request, and that property needs to contain the comments data later, for which Vue can then recognize the seting of that property to trigger a re-render. I'd personally not do this as I like to keep my reactive state and behaviours separated, but ... the above would work, technically. |
Beta Was this translation helpful? Give feedback.
I've had a closer look at the demo you posted and it has helped me a lot: thank you.
I created a slightly modified version to more closely replicate my situation here
In my version I can toggle the comments section on and off per blog post, which will initiate the (mock) fetch on first activation.
I really appreciate your help here.
Cheers, Stuart.