Search code examples
javascriptoauth-2.0svelte

Svelte store value from async script in variable


I'm new to svelte so maybe I'm missing something obvious. I want to use OAuth2 in my Svelte application. There is no npm package, so, I need to load it by using a regular <script>. I want to retrieve the user from the Google api and display it in a variable in my component. Currently I'm loading the script in a <svelte:head> component and this works fine. Here is my working code:

<svelte:head>
  <script src="https://apis.google.com/js/platform.js?onload=init" async defer></script>
  <script>
    function init() {
      gapi.load("auth2", function () {
        gapi.auth2
          .init({
            clientId: "my_clientId",
            apiKey: "my_apiKey",
          })
          .then(() => {
            GoogleAuth = gapi.auth2.getAuthInstance(); // Create instance
            if (GoogleAuth.isSignedIn.get()) { // If signed in, log name
              const profile = GoogleAuth.currentUser.get().getBasicProfile();
              console.log("Full Name: " + profile.getName());
            } else { // Else trigger login
              GoogleAuth.signIn();
            }
          });
      });
    }
  </script>
</svelte:head>

This code will console.log the username if the user is logged in, otherwise it will trigger a google login popup.

How would I store the user profile retrieved from GoogleAuth in a variable in my Svelte component instead of just logging it? I have tried these suggestions and also tried to pass an on:load={} function to my svelte:head> as shown here.


Solution

  • To call a function after the script in the <svelte:head> is loaded it is possible to call a function with on:load. Make sure to call this function with parentheses, like this: on:load="{yourFunction()}" and not on:load="{yourFunction}" (this is wat I did wrong).

    The final code looked like this:

    <script>
      function init() {
        gapi.load("auth2", function () {
          gapi.auth2
            .init({
              clientId: process.env.GOOGLE_CLIENT_ID,
              apiKey: process.env.GOOGLE_API_KEY,
            })
            .then(() => {
              const GoogleAuth = gapi.auth2.getAuthInstance();
              if (!GoogleAuth.isSignedIn.get()) {
                if (window.location.pathname !== "/login") {
                  window.location.href = "/login";
                }
              }
            });
        });
      }
    </script>
    
    <svelte:head>
      <script
        src="https://apis.google.com/js/platform.js"
        async
        defer
        on:load="{init()}">
      </script>
    </svelte:head>
    

    The init function is now in a regular script tag. We could also access the svelte store from here.