Sam
Sam

Reputation: 1838

Vue 3 composition Api: V-For loop not accessing data

I have this template

My issue is that location.drawnfeatures in template is not updating for some reason I can see I have the right data from console.log and I tested without 'v-for' and the code works

if I put v-if="location.drawnFeatures.length" I get error saying length is not defined..

I tried adding .value about everywhere

Why is vue3 not accessing data ?

<ol-feature v-for="(feature, index) in location.drawnfeatures" :key="'feature'+uid+index">
  <ol-geom-point :coordinates="feature.coordinates"></ol-geom-point>

location is defined like this:

props:{
 locationData:Object,
},
setup(props){
  const location = ref({
    center:[0, 0],
    zoom:5,
    coordinates:null,
    rotation: 0,
    name:null,
    title:null,
  })

 onMounted(() => {
  location.value = props.locationData && props.locationData.location ? props.locationData.location : location.value
  console.log(location.value)
 });
}

I also tried declaring prop in setup()

const locationData = toRef(props)

if I do console.log(locationData.value) I get undefined

but this is not working either

Upvotes: 0

Views: 2903

Answers (2)

Sam
Sam

Reputation: 1838

I am not sure why but this works: I had to stop using the prop directly and destructure location

first I had to declare in two places (don't ask me why)

props:{
  locationData:Object,
},
setup(props, context) {
  const locationData = toRef(props)

in mounted I did something like:

  if(props.locationData.location) {
    if(props.locationData.location.drawnFeatures) {
      locationFeatures.value = props.locationData.location.drawnFeatures
    }
    if(props.locationData.location.zoom) {
      zoom.value = props.locationData.location.zoom
    }

then transformed the property location into a method:

const location = () =>  { 
 return {
  center:center,
  drawnFeatures:drawnFeatures
}}

and modified the template

 <ol-feature v-for="(feature, index) in locationFeatures" :key="'feature'+uid+index">
    <ol-geom-point :coordinates="feature.coordinates"></ol-geom-point>

Upvotes: 0

InvisibleGorilla
InvisibleGorilla

Reputation: 376

If you destructure an object that you get via props, the destructured value will lose reactivity:

However, because props are reactive, you cannot use ES6 destructuring because it will remove props reactivity.

It seems that with location.value = props.locationData.location you are accessing a nested object value from a prop and it does not maintain reactivity.

Based on the code it looks like it should be possible to use the locationData prop directly in the for loop:

<ol-feature v-for="(feature, index) in locationData.location.drawnfeatures" :key="'feature'+uid+index">

You can also set a default object in the props and you might not need to define the location in the setup.

props: {
 locationData: {
  type: Object,
  default() {
   return {
    location: {
     center: [0, 0],
     zoom: 5,
     coordinates: null,
     rotation: 0,
     name: null,
     title: null,
    }
   }
  }
 }
}

Upvotes: 1

Related Questions