Angular Service: AppleID is not recognized following the loading of the Apple script

I'm new to this forum and have been struggling to find a solution for my problem. I am attempting to integrate AppleConnect into my Angular 8 app with the following approach:

I have created an appleService.ts file that dynamically generates the Apple script and appends it to the DOM. Then, I initialize AppleID.auth once the 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');
                });
            });
        });
    }
}

The first part of the implementation is working correctly, but I am encountering the following error:

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

Interestingly, when I type AppleID in my browser console, it exists. I feel like I am missing something here but can't quite figure it out...

Any assistance would be greatly appreciated!

Answer №1

I managed to solve the issue by utilizing an arrow function for the callback;

            let appleConnectSuccess = (AppleID) => {
                AppleID.auth.init({
                    clientId    : "com.example",
                    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/en_US/appleid.auth.js";
                fjs.parentNode.insertBefore(js, fjs);
                js.addEventListener("load", () => cb(AppleID));
            }(document, 'script', appleConnectSuccess));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the difference between TypeScript's import/as and import/require syntax?

In my coding project involving TypeScript and Express/Node.js, I've come across different import syntax options. The TypeScript Handbook suggests using import express = require('express');, while the typescript.d.ts file shows import * as ex ...

Using TypeScript to ensure class parameter types without affecting properties

I am tasked with defining a schema for "operations" that will be used in my application. This schema must be easily extendable for other groups of "operations" and should include a dictionary of settings for each keyword. Eventually, a "generic caller" wi ...

Elements recognized worldwide, Typescript, and a glitch specific to Safari?

Consider a scenario where you have a select element structured like this: <select id="Stooge" name="Stooge"> <option value="0">Moe</option> <option value="1">Larry</option> <option value="2">Curly</option ...

How can I effectively address process.on test in TypeScript Mocha Testing with the help of a Sinon Spy?

I need to conduct a test on the warning process for my Typescript project. The specific code that I am attempting to test is shown below: process.on('warning', (warning) => { LoggingService.info('Warning, Message: ' + warning.mes ...

The onClick function for a button is not functioning properly when using the useToggle hook

When the button is clicked, it toggles a value. Depending on this value, the button will display one icon or another. Here is the code snippet: export const useToggle = (initialState = false) => { const [state, setState] = useState(initialState); c ...

Can Node.js version 11 support node-sass in Angular projects?

I'm encountering a compilation error with my code. Could this be due to the node version? Does node-sass work with all versions of node? If not, how can I resolve this issue? Compilation error: Unable to locate module 'node-sass' ...

Can you provide input to the reducer function?

In the creator, an action is defined like this: export const actionCreators = { submitlink: (url: string) => <SubmitLinkAction>{ type: 'SUBMIT_LINK' } } In the component that calls it: public render() { return <div> ...

Is it impossible to use type as a generic in TypeScript?

Struggling with TypeScript in React and encountered an issue. I decided to use a generic to build an abstracted class related to Axios. However, I ran into an ESLint error when using any as the type parameter for my generic. ESLint: Unexpected any. Specif ...

There was an issue with the layout detection in Angular. The app-layout selector could not find a matching element in the code

Currently diving into the world of Angular and embarking on my first project, I've hit a roadblock. After initiating a terminal with the server, all I get is a blank page when I load my browser. Upon inspecting the page using f12, an error message pop ...

"The Zorro table is filled with items of various types, although unfortunately, the Intellisense is not as accurate as it

Imagine a scenario where you have a basic table set up: <nz-table #table [nzData]="users"> <thead> <tr> <th>Id</th> <th>First Name</th> <th>Last Name</th> </tr> ...

Discovering the breakpoints for Angular ng-bootstrapUncover the angular ng

Utilizing ng-bootstrap in my latest project has allowed me to easily create a grid with breakpoints, like so: <div class="row"> <div class="col-sm-12 col-md-6 col-xl-4"></div> </div> Although these breakpoints are convenient, ...

What is the best way to combine API calls using rxJs subscribe and map in Angular?

Currently, I am executing multiple API requests. The first one is responsible for creating a User, while the second handles Team creation. Upon creating a User, an essential piece of information called UserId is returned, which is crucial for the Team cre ...

The solution to accessing a global variable within the onerror event of an audio object

My goal is to retrieve the value of the isDisabled variable from within the audio.onerror function and then reset it, but I am encountering difficulty in achieving this. public isDisabled: boolean = false; private verifyPrompt(url: string): boolean{ ...

Challenges with implementing ng2-auto-complete in Angular2

I successfully integrated the Angular 2 ng2-auto-complete component into my project by following this helpful tutorial. The code is also available on GitHub. The current challenge I am encountering involves the formatting of my data source. It is structur ...

Implementing a scroll-triggered class addition in Angular

I am currently refreshing my knowledge of Angular. After installing AngularCLI, I am attempting to transition from using jQuery to add a class on scroll. Would it be necessary to utilize [ngClass] in order to check a variable with window location? Right ...

Tips on transforming data stored in an array into a nested array structure using Angular 13

Just starting out with Angular and I'm looking to convert my data into a nested array format in Angular 13. If anyone has a StackBlitz example, that would be greatly appreciated! This is the data I've retrieved from a random API: "data& ...

Connecting the outcome of a Promise with an Observable

Forgive me if this is a silly question. I searched high and low but couldn't find the answer I need. I'm trying to figure out how to pass the value for index, which is returned in the Promise, as an argument to my Observable: deleteFavorite(tok ...

Exploring Angular 2's @Input and @Output Directives

I'm unsure about whether I should be using @Input and @Output. From my understanding, these decorators are typically used when you want to establish communication between a parent and child component. Can you confirm or correct me on this? I have 3 c ...

Combining various API requests within a Vue component, which includes a for loop

I'm delving into the world of API chaining, specifically trying to link two different API calls within a 'notes' Vue component. My knowledge of promises is basic at best, but I'm eager to enhance my skills in this area. The initial API ...

To handle a 400 error in the server side of a NextJS application, we can detect when it

I'm facing a situation where I have set up a server-side route /auth/refresh to handle token refreshing. The process involves sending a Post request from the NextJS client side with the current token, which is then searched for on the server. If the t ...