0

In my Vue app I have an image element with a bound src. this code is in a stepper. In one step the user selects a picture to upload an in the next step the image gets shown (which works as intended). However I am trying to initiate a library on the element in the next step (the Taggd library) but the element seems to be undefined.

I tried the nextTick() to wait for the image to load but without luck.

the image element:

<div class="orientation-landscape">
    <div class="justify-center q-px-lg">
        <img v-if="photo.url" :src="photo.url" id="workingPhoto"
        style="width: 80vw;" ref="workingPhoto"/>
    </div>
</div>

The functions. I first use uploadFile to set the url of the image element and go to the next step where the image will be loaded. then I call initTaggd() on the nextTick however that fails because the element is undefined.

uploadFile(file) {
  const self = this;
  self.photo.file = file;
  self.setPhotoUrl(file);
  self.$refs.stepper2.next();
  console.log('We should be at next step now. doing the init');
  self.nextTick(self.initTaggd());
},

setPhotoUrl(file) {
  const self = this;
  self.photo.url = URL.createObjectURL(file);
  console.log('ping1');
},

initTaggd() {
  const self = this;
  const image = document.getElementById('workingPhoto');
  console.log('image:', image);     //THIS RETURNS UNDEFINED
  console.log('Trying ANOTHER element by refs:', self.$refs.stepper2);     // This returns the element
  console.log('trying the real element by reference', self.$refs.workingPhoto);     // Returns undefined again
  const taggd = new Taggd(image);      //All this here fails because image is undefined.
  console.log('ping2.5');
  taggd.setTags([
    self.createTag(),
    self.createTag(),
    self.createTag(),
  ]);
  console.log('ping3');
},

I think I am looking for a way to wait for the image to fully load before calling initTaggd() but I am lost on how to achieve this.

Travinns
  • 263
  • 1
  • 3
  • 13
  • Btw, I also tried removing the v-if in the image element. Same result. – Travinns Jan 21 '19 at 14:36
  • You parent and stepper should be communicating via props and events, not by you calling its methods via refs. Your architecture is not very Vueish. – Roy J Jan 21 '19 at 15:03

1 Answers1

2

You could listen for the load event:

<img 
    v-if="photo.url" 
    id="workingPhoto"
    ref="workingPhoto"
    :src="photo.url"
    style="width: 80vw;" 
    @load="initTaggd"
/>
Stephen Thomas
  • 13,843
  • 2
  • 32
  • 53
  • Do you have the link to documentation for `@load` event? – ljubadr Jan 21 '19 at 18:51
  • Don't think it's actually in any standard when applied to image elements though most (all?) browsers support it. FWIW, w3schools [documents it](https://www.w3schools.com/jsref/event_onload.asp). Closest official reference is [here](https://w3c.github.io/uievents/#event-type-load) where it generically says that the event applies to elements. – Stephen Thomas Jan 21 '19 at 21:21
  • Many thanks! I thought it's vue speciffic, so my search was off :) – ljubadr Jan 21 '19 at 21:30