0

I'm getting crazy on this.

This is the code, is a component I'm using inside a form to show the preview of a video when I paste an url into an input:

<template>
  <div class="row">
    {{embedData}}
    <input v-model="embedData" name="content[body]" id="content_body">
    <div class="col-md-6">
      <div class="form-group">
        <div class="form-group url optional content_video_url form-group-valid">
          <label for="content_video_url" class="url optional">Url del video</label>
          <input @change="forceRerender" v-model="url" type="url" value="" name="content[video_url]" id="content_video_url" class="form-control is-valid string url optional">
        </div>
      </div>
    </div>
    <div class="col-md-6">
      <div class="video-responsive"
        <o-embed ref="embed" :url="url" :key="componentKey"></o-embed>
      </div>
    </div>

  </div>
</template>

<script>

import oEmbed from './oEmbed'
import EventBus from '../utils/eventBus'

export default {
  components: {
    oEmbed
  },

  props: {
    video_url: String,
    video_caption: String
  },

  created: function() {
    this.url = this.video_url;
    this.caption = this.video_caption;
  },
  mounted: function() {
    EventBus.$on('HTML', function (payLoad) {
      this.embedData = payLoad
      console.log('payLoad:' + this.embedData);
      console.log('arrived');
    });
  },
  data: function() {
    return {
      url: '',
      caption: '',
      componentKey: 0,
      embedData: ''
    }
  },
  methods: {
    forceRerender () {
      this.componentKey = this.componentKey + 1;
    }
  }
}
</script>

o-embed is a component, and I've added a simple bus emit function when the component is update:

 mounted: function() {
    EventBus.$on('HTML', function (payLoad) {
      this.embedData = payLoad
      console.log('payLoad:' + this.embedData);
    });
  }

If I check the console log I have this

payLoad: <iframe src="https://player.vimeo.com/video/596287904?app_id=122963&amp;h=d77f5dc57c" width="426" height="240" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen title="Raritan Bay Cruisers-Hopelawn New Jersey CruisebNight 8-31-2021.wmv"></iframe>

Everythink is working, this.embedData looks ok, I have the log, but when I render embedData in my view it's empty.

I give an additional info: I'm forcing the re-rendering of the embed component, but I don't think it's related.

Any ideas?

3
  • when/where do you render embedData in your view ? I can't see it Commented Sep 9, 2021 at 14:17
  • Sorry I just change html to embedData for the question, buy as you can see in the template I have {{embedData}} and also the input form then I need to update the backend. But also looking at Vue Developer Tools in Chrome the data is not present. Only inside the log I have the data, then it disappear Commented Sep 9, 2021 at 14:22
  • Not sure if a change in componentKey will rerender everything. I thought Vue just rerenders portions of the template where data (or values depending on it) are used. How about forcing Vue re-render the right way Commented Sep 9, 2021 at 14:36

2 Answers 2

2

You're using an anonymous function. this inside the anonymous function does not provide the component's context.

Try using an arrow function instead:

EventBus.$on('HTML', (payLoad) => {
      this.embedData = payLoad
      console.log('payLoad:' + this.embedData);
    });
Sign up to request clarification or add additional context in comments.

3 Comments

Or you can bind the function to parent context
Yes, that's another way too. I personally prefer this way since that's the main reason why ES6 introduced arrow functions.
I agree, on the other hand, but there are occassions, such as having some utility method used application wide, then you cannot use arrow function (because it takes context of where it was defined, rather than executed), but function with bind.
1

Mythos found the issue (at least one of them). The mustache template (double curly braces) interpret contents as plain text, not html. If you want to inject raw html into your page you should do something like

<div v-html="embedData"></div>

instead (https://v2.vuejs.org/v2/guide/syntax.html#Raw-HTML)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.