Empty .value when using the setup() method in compositionApi
philipimperato opened this issue · comments
Question about compositionApi
and useFind
When querying my Notes service:
const { items, isPending } = useFind({ model: Note, params: { query } })
return { items }
I have a populate items on refresh and on when navigating to the route through the app
Now, when I want to filter the date:
const items2 = items.value.filter(v => v)
return { items, items2 }
items
is always populated, but item2
is only populated when I navigate to the component through the app and is empty on refresh. I understand you lose the store... and it appears that the value.filter
fires before the data is loaded... so I'm wondering what the point of filtering within the setup method is?
The example shows it doing this: https://vuex.feathersjs.com/composition-api.html#working-with-refs
My only solution is to only return the items RefImpl
and filter in a computed property or something, which feels janky and not what the examples encourages.
Any thoughts?
Here is the component. To recap items.length
= 1 always, but items2.length
will show 0 on refresh of page.
<template lang="pug">
.player-score( v-if="haveLoaded" )
v-row(justify="center")
v-col.text-center(
cols="10"
)
.text-h1 {{ items.length }}
v-col.text-center(
cols="10"
)
.text-h1 {{ items2.length }}
</template>
<script>
import { useFind } from 'feathers-vuex'
import { computed } from '@vue/composition-api'
export default {
name: 'PlayerScore345',
setup (props, context) {
const { Note } = context.root.$FeathersVuex.api
const noteParams = computed(() => { return { query: { $limit: 1 } } })
const { items, haveLoaded } = useFind({ model: Note, params: noteParams })
const items2 = items.value.filter(v => v)
console.log(items, haveLoaded)
return { items, items2, haveLoaded }
}
}
</script>
<style lang="scss" scoped>
</style>
Can you share the whole component please?
It's hard to tell without the rest of the code.
I'd say that filtering on the ref value and returning raw value make it loose reactivity.
You should make it a computed to make it works.
At first sight, it seem's to be a problem with vue 3 reactivity.
@marshallswain It appears that the docs show the filtering on the .value
, placing into a variable and returning it within the setup()
method. If the reactivity is lost with filter()
, wouldn't that mean that the variable is created prior to items
being populated?
The variable is always created prior to items being populated, but usually items values are updated after being populated.
The response of the find request has not yet arrived, and as the reactivity has been lost it will no be updated will the requested values.
But once the component is reloaded, the items are there because they are already in the store.
Yup, I figured that, but was thrown off by the usage within the docs
https://vuex.feathersjs.com/composition-api.html#usefind
const { items: todos } = useFind({ model: Todo, params: todosParams })
// Notice the "todos.value"
const completeTodos = todos.value.filter(todo => todo.isComplete)
const incompleteTodos = todos.value.filter(todo => !todo.isComplete)
This makes me think I'm doing it wrong.. when it doesn't appear that I am based on what I'm seeing in practice.
Yep, those two todos arrays should be wrapped in a computed...
ah thanks @philipimperato for pointing out the inconsistency in the docs. And as always, thank you @J3m5 for pitching in to see the fix!
I just pushed up a fix for the docs that wraps those two filtered arrays into computed properties.