3

I'm trying to use AmazonPay in my VueJS app. I was able to get the javascript to load, but I'm getting an error when I try to display the button. It seems like there would be plenty of examples of AmazonPay out there, but nothing for VueJS.

Here is the Javascript console error:

Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
    at Object.C.Button (Widgets.js:2)
    at window.onAmazonPaymentsReady (playmix.vue?4ede:39)
    at Widgets.js:2
    at Widgets.js:2
    at HTMLScriptElement.a (Widgets.js:2)

I put the javascript to be called by the Amazon javascript in the mounted section of my component:

 mounted() {
    window.onAmazonLoginReady = function () {
      amazon.Login.setClientId(
        "CLIENT_ID"
      );
    };
    window.onAmazonPaymentsReady = function () {
      showButton();
    };
    function showButton() {
      var authRequest;
      OffAmazonPayments.Button(
        "AmazonPayButton",
        "CLIENT_ID",
        {
          type: "PwA",
          color: "Gold",
          size: "medium",
          authorization: function () {
            loginOptions = { scope: "profile", popup: "false" };
            authRequest = amazon.Login.authorize(
              loginOptions,
              "https://localhost/test"
            );
          },
        }
      );
    }
    let amazonpay = document.createElement("script");
    amazonpay.setAttribute(
      "src",
      "https://static-na.payments-amazon.com/OffAmazonPayments/us/sandbox/js/Widgets.js"
    );
    amazonpay.setAttribute("type", "text/javascript");
    amazonpay.async = true;
    document.head.appendChild(amazonpay);
},

In my component I have a tag. I found a React package for AmazonPay, but so far I haven't found many examples for use in Vue. There is a full blown commerce library for Vue, but it seems overkill for my project. Any ideas on how to solve this issue?

9
  • Do you have <div id="AmazonPayButton"></div> in the template? Commented Aug 21, 2020 at 7:52
  • Also, you might need to set the script in created instead of mounted. You're appending it after calling the different Amazon functions Commented Aug 21, 2020 at 7:54
  • @Daniel_Knights I thought I had already tried within created. I just moved the code back to created and I get the same error. The exact line within Amazon's Widgets.js is: }, H = M.getElementsByTagName("img"), k = 0; k < H.length; k++) Commented Aug 21, 2020 at 8:01
  • Did you move just the script section of the code into created or the entire thing? Commented Aug 21, 2020 at 8:04
  • 1
    Ah ha! I put the <div id="AmazonPayButton"></div> in the index.html of the Vue app and it shows up now! So this seems to have something to do with how Vue is building out the tag within the component. Commented Aug 21, 2020 at 18:42

1 Answer 1

1

I just ran into this same issue and solved it by wrapping the call to showButton() with Vue's .$nextTick() function. This will run your function once the template is done being rendered.

The following should work in your example if you just replace it inside your mounted() section.

If you can use ES6:

window.onAmazonPaymentsReady = () => {
  this.$nextTick(function(){
    showButton();
  })
};

if not, then this should work:

var that = this;
window.onAmazonPaymentsReady = function () {
  that.$nextTick(function(){
    showButton();
  })
};
Sign up to request clarification or add additional context in comments.

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.