javascriptvue.jsvuejs3vue-component

How to wait for an external script to be ready in Vue 3?


I am trying to integrate Google Pay as a component in an application. I need to load the Google Pay Javascript file before I perform any actions. This is what I am doing:

onMounted(()=>{
  const scripts = [
    "https://pay.google.com/gp/p/js/pay.js",
  ];

  // Append the pay.js script to the <head> tag
  scripts.forEach(script => {
    let tag = document.createElement("script");
    tag.setAttribute("src", script);
    tag.setAttribute("async", true);
    
    document.head.appendChild(tag);
  });

  //Check if Google Pay exists
  function isGooglePayReady(){
    if('google' in window && Object.keys(window.google).length) {
      loadGooglePay()
    }
}

// Have to currently use a setTimeout to wait for script to load
setTimeout(()=> isGooglePayReady(), 500);

I set the timeout to 500 arbitrarily because I don't know how long it at takes for the https://pay.google.com/gp/p/js/pay.js script to load be available.

Is there a better way to wait for the script to load and be ready than using a setTimeout() function?


Solution

  • Yes, instead of using setTimeout(), you can listen for the script's load event to ensure it has been fully loaded before executing your loadGooglePay() function.

      const scriptUrl = "https://pay.google.com/gp/p/js/pay.js";
    
      // Check if script already exists to avoid duplicate loading
      if (!document.querySelector(`script[src="${scriptUrl}"]`)) {
        const script = document.createElement("script");
        script.setAttribute("src", scriptUrl);
        script.setAttribute("async", true);
    
        script.onload = () => {
          if (window.google) {
            loadGooglePay(); // Call your Google Pay initialization function here
          }
        };
    
        script.onerror = () => {
          console.error("Failed to load Google Pay script.");
        };
    
        document.head.appendChild(script);
      } else {
        // Script already loaded, initialize immediately
        if (window.google) {
          loadGooglePay();
        }
      }
    });
    
    

    Explanation:

    1. Uses the onload event: This ensures loadGooglePay() runs only after the script is fully loaded.
    2. Prevents duplicate script loading: It first checks if the script is already present before adding a new one.
    3. Handles errors: If the script fails to load, it logs an error message.
    4. Immediate initialization: If the script is already loaded (e.g., due to hot reloading), it calls loadGooglePay() right away.

    This method is more reliable than setTimeout() and ensures that the script is only loaded once, improving efficiency