0

I'm trying to load an external script inside a Vue component.

It consists in a script that uses a data value and other attributes to create an URL to be inserted in an iframe src so it mounts a payment form with the data value as the price.

The problem is that I have no control over the script running.

It only runs once the page is refreshed, and obviously with the initial value of the data. I need to run the script every time I open the dialog with the component inside passing the updated data value.

I've tried v-ifs, v-shows, watchers, I'm really in the dark here.

This is the script I'm trying to run: https://hpp-service.genome.eu/paymentPage.js


UPDATE I added a watcher to the deposit amount that is received by prop, so I delete the existing script and rerun it to pass the new data value.

Now it just works if I edit the deposit amount. If I route to the payment page and click on deposit it opens an empty iframe.

Here is my component code:

`<template>
  <div>
    <form class="pspPaymentForm"></form>
    <iframe
      v-show="iframe.loaded"
      id="psp-hpp-xxx"
    ></iframe>
  </div>
</template>

<script>
export default {
  props: ["deposit", "dialogOpened"],
  data() {
    return {
    // The payment API expects an array of objects
      product: [
        {
          productId: "ID12345",
          productType: "fixedProduct",
          productName: "Demo fixed product",
          currency: "EUR",
          amount: 100,
          productDescription: "Deposit amount",
        },
      ],

      iframe: {
        loaded: false,
      },
    };
  },

  watch: {
    deposit() {  
      let genomeScript = document.getElementsByClassName("pspScript");
      if (genomeScript[0] !== undefined) {
        genomeScript[0].remove();
      }
      this.product[0].amount = this.deposit;
      this.createForm();
      
    },


    dialogOpened() {

      let genomeScript = document.getElementsByClassName("pspScript");
      if (this.dialogOpened === true) {
        if (genomeScript[0] !== undefined) {
          genomeScript[0].remove();
        }
        this.product[0].amount = this.deposit;
        this.createForm();
      }
    },
  },


  methods: {
    load() {
      this.iframe.loaded = true;
    },

    createForm() {
      let formy = document.getElementsByClassName("pspPaymentForm");
      let genomeScript = document.createElement("script");
      genomeScript.setAttribute(
        "src",
        "https://hpp-service.genome.eu/paymentPage.js"
      );
      genomeScript.setAttribute("class", "pspScript");
      genomeScript.setAttribute("type", "application/javascript");
      genomeScript.setAttribute("data-iframe_allowed", "true");
      genomeScript.setAttribute("data-iframesrc","https://hpp-service.genome.eu/hpp");
      genomeScript.setAttribute("data-buttontext", "Deposit!");
      genomeScript.setAttribute("data-name", "Application");
      genomeScript.setAttribute("data-key", "zzz");
      genomeScript.setAttribute("data-signature", "xxx");
      genomeScript.setAttribute("data-type", "integrated");
      genomeScript.setAttribute("data-width", "auto");
      genomeScript.setAttribute("data-height", "auto");
      genomeScript.setAttribute("data-payment_method", "Credit card");
      genomeScript.setAttribute("data-customproduct",JSON.stringify(this.product));
      this.load();
      formy[0].insertAdjacentElement("beforebegin", genomeScript);
    },
  },
  beforeDestroy() {
    let genomeScript = document.getElementsByClassName("pspScript");
    if (typeof genomeScript[0] !== "undefined") {
      genomeScript[0].remove();
    }
    this.iframe.loaded = false;
  },
};
</script>
`
  • Obviously the script is designed to watch `window.onLoad` and initialize itself - but since you have the source code you can simply convert it from CommonJS to ES6 and then call its functions only when you need to. – IVO GELOV Jun 25 '20 at 11:08
  • Can you create a minimal example? – Gabriel Willemann Jun 25 '20 at 11:26
  • do you mean this https://stackoverflow.com/questions/45047126/how-to-add-external-js-scripts-to-vuejs-components – Bas Jun 25 '20 at 11:37
  • @IVOGELOV considering it is an payment api, isn't it bad practice? – Gaya Rabello Jun 29 '20 at 09:19
  • @GabrielWillemann I updated the post with the component code. – Gaya Rabello Jun 29 '20 at 09:19
  • @Bas yes, this is the starting point, but I needed more control than loading on mount. – Gaya Rabello Jun 29 '20 at 09:20
  • My point was that you can change the script so you can call its `init` function at the exact moment you need/want instead of `window.onload` as the script is currently doing. If you do not want to change the script - you can reference it from a `form.html` file and load this file (the HTML) through an IFRAME. Your watcher for the amount will reload the IFRAME when the amount changes. – IVO GELOV Jun 29 '20 at 11:20

0 Answers0