Angular Service : AppleID is not defined after Apple script loaded

Viewed 1226

This is my first post here, I tried to find the solution but did not find any related issue. I'm trying to implement the AppleConnect into my Angular 8 app. This is how I do:

I created an appleService.ts file which dynamically creates the Apple script and append it to the DOM, and then initialize the AppleID.auth once script is loaded.

import {isBrowser} from '../../appModule/platformUtil';
import {KartableConfig} from '../../commonModule/services/kartableConfig';
import {Injectable} from '@angular/core';
import {KartableLogger} from '../../appModule/services/KartableLogger';
import { environment } from '../../environments/environment';


declare let AppleID : any;

@Injectable({
    providedIn: 'root',
})
export class AppleService {
    applePromise: Promise<void>;

    constructor(private config: KartableConfig,
                private logger: KartableLogger) {
    }

    private initApple(redirectUri: string): Promise<void> {
        if (!isBrowser()) {
            this.logger.error('Apple init called server side');
            return null;
        }
        if (!this.applePromise) {
            this.applePromise = new Promise(resolve => {
                const appleConnectLoaded = () => {
                    AppleID.auth.init({
                        clientId : environment.appleConnectClientId,
                        scope : 'name email',
                        redirectURI : redirectUri,
                        usePopup : true
                    });
                    resolve();
                };

                (function(d, s, id){
                    var js, fjs = d.getElementsByTagName(s)[0];
                    if (d.getElementById(id)) {return;}
                    js = d.createElement(s);
                    js.type = 'text/javascript';
                    js.id = id;
                    js.async = true;
                    js.src = "https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/fr_FR/appleid.auth.js";
                    fjs.parentNode.insertBefore(js, fjs);
                    js.onload = appleConnectLoaded();
                }(document, 'script', 'apple-connect'));
            });
        }
        return this.applePromise;
    }

    public login(redirectUri: string): Promise<{ [key: string]: string }> {
        return new Promise((resolve: Function, reject: Function) => {
            this.initApple(redirectUri).then(() => {
                document.addEventListener('AppleIDSignInOnSuccess', (data) => {
                    resolve(data);
                });
                document.addEventListener('AppleIDSignInOnFailure', (error) => {
                    reject('Apple connect failed');
                });
            });
        });
    }
}

First part is going well, but i get the following error:

ReferenceError: AppleID is not defined at appleConnectLoaded (appleService.ts:34)

Strange part is that when I type AppleID into my browser console, it exists. I'm missing something here but can't put the hand on it... Thanks for your help !

1 Answers

I solved it by passing the callback as an arrow;

            let appleConnectLoaded = (AppleID) => {
                AppleID.auth.init({
                    clientId    : "com.something",
                    scope       : 'name email',
                    redirectURI : window.location.protocol + "//" + window.location.hostname + "/apple",
                    usePopup    : true
                });
                resolve();
            };

            (function(d, s, cb){
                var js, fjs = d.getElementsByTagName(s)[0];
                js = d.createElement(s);
                js.src = "//appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/sv_SE/appleid.auth.js";
                fjs.parentNode.insertBefore(js, fjs);
                js.addEventListener("load", () => cb(AppleID));
            }(document, 'script', appleConnectLoaded));
Related