1

I've a v-for loop in my component and I need to update input value after I got it from the server. Below I provide full code of the component and my current issue - I don't understand how to change and even refer to any input. I marked in capital letters the row with code which does not work and provide more details after the code snippet

<template>
<div class="allPlaces__entrance" v-for="(entrance, index) in places.entrance" v-bind:key="index">
  <div class="allPlaces__infoBlock">
   <div>
    <div class="allPlaces__available">
     <span class="allPlaces__label allPlaces__label--places">Доступно мест:</span>
     <span class="allPlaces__data">&nbsp;{{entrance.vacant_places}} 
     </span>
    </div>
    <div class="allPlaces__title allPlaces__title--entrance">{{getEntranceName(entrance)}}</div>
    </div>
    <div class="allPlaces__price">
     <span class="allPlaces__label">Цена: </span>
     <span class="allPlaces__data">{{entrance.price}}</span>
    </div>
    </div>

    <div class="allPlaces__orderBlock">
     <div class="allPlaces__inputBlock">
      <input class="allPlaces__input" type="number" name="amount" v-model="entrance.value" :ref="entrance.id" @blur="showLabel($event, index)">
      <label class="allPlaces__label allPlaces__label--input"
                     @click="hideLabel($event, index)">Количество мест
      </label>
     </div>
    </div>
  </div>
</div>
</template>

script>
import vueMethods from '../../mixins/methods'
import { mapState } from 'vuex'

export default {
  name: 'allPlaces',
  mixins: [vueMethods],
  data () {
    return {
      showTitle: ''
    }
  },
  mounted () {
    this.$nextTick(function () {
      window.addEventListener('resize', this.updateAllPlacesOnResize)
      this.setupAllPlaces()
    })
  },
  watch: {
    sessionId: function () {
      console.log('this.sessionId ', this.sessionId);
      // Как только создан seesionId запрашиваем колличество мест в корзине
      this.getPlacesInCart();
      let ref = this.$refs; // HERE IS MY ISSUE
      console.log(this.$refs[15129]); // UNDEFINED
    },
    places: function () {
      console.log(this.places.entrance[0].id);
    }
  },
  computed: {
    ...mapState({
      db: state => state.onload.eventData.currentDb,
      agentId: state => state.onload.eventData.currentAgent,
      eventId: state => state.onload.eventData.currentEvent,
      modals: state => state.modals,
      metric: state => state.onload.eventData.metric,
      section: state => state.onload.eventData.section,
      show: state => state.onload.eventData.show,
      event: state => state.onload.eventData.event,
      building: state => state.onload.eventData.building,
      hall: state => state.onload.eventData.hall,
      places: state => state.onload.eventData.places,
      placesSeated: state => state.onload.eventData.places.place,
      sessionId: state => state.cart.sessionId,
      ticketsInCart: state => state.cart.ticketsInCart
    })
  }
}
</script>

The object I got when I call console.log(this.$refs);

{15129: [input.allPlaces__input]
15131: [input.allPlaces__input]
15132: [input.allPlaces__input]
15133: [input.allPlaces__input]
15137: [input.allPlaces__input]}

But if I call console.log(this.$refs[15129]);, I'm getting undefined

Please advise

Asim Khan
  • 1,969
  • 12
  • 21
Evgeny Ladyzhenskiy
  • 151
  • 1
  • 3
  • 15
  • It's possible it's not rendered yet, try something like console.log(JSON.parse(JSON.stringify(this.$refs))) to check if it really exist – Chris Li Aug 30 '19 at 13:19
  • `places.entrance['15129'].value = newValue` should do the trick, shouldn't it? – whereo Aug 30 '19 at 13:23
  • @ChrisLi Got empty object. Can't understand why so if `console.log(this.$refs);` shows object which I provided at the end of my post – Evgeny Ladyzhenskiy Sep 01 '19 at 15:59
  • @whereo Your idea would possibly could be a base for other way which I'll try tomorrow. Withal I'd like to solve the current issue as soon it would make my live way more easier) – Evgeny Ladyzhenskiy Sep 01 '19 at 16:10
  • console.log doesnt work how you think it works. you can read about it here https://stackoverflow.com/questions/11284663/console-log-shows-the-changed-value-of-a-variable-before-the-value-actually-ch – Chris Li Sep 01 '19 at 19:30

1 Answers1

0

What probably happens is that the watcher for sessionId executes before there is anything in places.entrance. This means that no elements with :ref are rendered so this.$refs is empty. You can validate this by adding:

console.log(Object.keys(this.$refs));

to see the current refs when your watcher code executes.

Please note this part of the documentation:

An important note about the ref registration timing: because the refs themselves are created as a result of the render function, you cannot access them on the initial render - they don’t exist yet! $refs is also non-reactive, therefore you should not attempt to use it in templates for data-binding.

tony19
  • 125,647
  • 18
  • 229
  • 307
bernie
  • 9,820
  • 5
  • 62
  • 92
  • The thin is that there are not empty object but those I provided at the end of my post. But the strange thing that I've tried `console.log(Object.keys(this.$refs));` and got empty array(( – Evgeny Ladyzhenskiy Sep 01 '19 at 15:55
  • It's not strange at all. `this.$refs` is only "expanded" and therefore its content "looked up" when you click on it in the console. At that point all the refs have been created. `console.log(Object.keys(this.$refs));` makes sure to display the keys present on the object at the time it's logged, not when you click on it. – bernie Sep 01 '19 at 21:51