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

Transform Material UI Typography to css-in-js with styled-components

Can Material UI elements be converted to styled-components? <Container component="main" maxWidth="XS"> <Typography component="h1" variant="h5"> Sign in </Typography> I attempted this for typography but noticed that t ...

Learning about the intricacies of backend Node.js through Angular using GET requests

I am having trouble retrieving the query parameters from a frontend GET request on the backend side. I have attempted to use url and query, but still need assistance fetching the query on the nodejs side. Can someone recommend a method that would allow me ...

Eliminate spacing in MaterialUi grids

As I work on a React project, I am faced with the task of displaying multiple cards with content on them. To achieve this layout, I have opted to use MaterialUi cards within Material UI grids. However, there seems to be an issue with excessive padding in t ...

The ListView is not updating correctly as expected

Currently, I am working on a project where I have a Page with a ListView that displays items from an ObservableArray of Expense objects. The issue I am facing is that when I scroll down, the amount property of some Expense rows is not being displayed. Howe ...

Resolving NestJS Custom Startup Dependencies

In my setup, I have a factory responsible for resolving redis connections: import {RedisClient} from "redis"; export const RedisProvider = { provide: 'RedisToken', useFactory: async () => { return new Promise((resolve, reject ...

Tips for obtaining the width of a child element during a resize event in an Angular application

When resizing the window, I am attempting to determine the width of a specific sub-component. If I want to retrieve the entire app's width, I can use the following code: @HostListener('window:resize', ['$event']) onResize( ...

Which is the optimal choice: subscribing from within a subscription or incorporating rxjs concat with tap?

After storing data in the backend, I proceed to retrieve all reserved data for that specific item. It is crucial that the data retrieval happens only after the reservation process to ensure its inclusion. Presented with two possible solutions, I am cont ...

Error in Typescript: The identifier 'Proxy' is unknown

I'm trying to create a new variable using the Proxy type from the ES6 specification: myProxy: Proxy; However, I'm encountering the following error: Cannot find name 'Proxy'. Can anyone point me in the right direction to resolve th ...

Steps to implement the click functionality on the alert controller and modify the language in Ionic 4

I am currently developing a multilingual Ionic 4 app and have implemented the alert controller to display language options. However, I am facing an issue on how to dynamically change the language based on user selection. Below is my app.component.ts code ...

What is the best way to implement a custom NgbDateParserFormatter from angular-bootstrap in Angular 8?

Currently, I am working on customizing the appearance of dates in a form using Angular-Bootstrap's datepicker with NgbDateParserFormatter. The details can be found at here. My goal is to display the date in the format of year-month-day in the form fi ...

Encountering an issue while attempting to make an in-app purchase with Ionic 3 and Cordova - receiving the error message "Sorry, the item you are trying to

In the process of developing my app with IONIC 3 and Angular 4, I have integrated the following Ionic plugin for in-app purchases: https://ionicframework.com/docs/native/in-app-purchase/ Once the plugin was installed, I included the "play_store_key" in t ...

Angular 2 Material Primary Focus

Struggling with altering the foreground color in Angular 2 material? Specifically, the text in the toolbar displays as black. I attempted to adjust it using the following styles: @import '~@angular/material/theming'; $primary: mat-palette($mat- ...

The typescript MenuProvider for react-native-popup-menu offers a range of IntrinsicAttributes

Looking to implement drop-down options within a Flatlist component, I've utilized the React Native Popup Menu and declared MenuProvider as the entry point in App.tsx. Encountering the following error: Error: Type '{ children: Element[]; }' ...

Exploring the capabilities of the Angular 2 expression parser alongside the functionality of the

Is there a way to create an equivalent of the Angular 1.x ngInit directive in Angular 2? I am familiar with the ngOnInit hook, which is recommended for initialization code. The ngInit directive seems like a quick and declarative way to prototype or fix a ...

The functionality of Angular router.navigate is not supported within Material Autocomplete

Currently, I am working on developing an autocomplete feature for a search functionality that allows users to look up products and navigate to a single product page by clicking on a specific product with its ID in the URL. To implement this, I am using An ...

Implementing global user authentication state with Zustand in Next.js version 13.4.9

I'm grappling with incorporating zustand into my Next.js 13.4.9 app, specifically for managing global authentication state. Below is the code snippet I have in my application: zustand store: // /src/store/AuthStore.ts import { create } from 'zu ...

Create a debounce click directive for buttons in a TypeScript file

I'm facing an issue with implementing debounce click on a dynamically added button using TypeScript. I need help with the correct syntax to make it work. private _initActionsFooter(): void { this.actionsFooterService.add([ { ...

The npm audit command flagged an issue with an invalid tag name,

Whenever I run npm audit on a directory containing the project's package.json and package-lock.json, I encounter the following error message: 0 info it worked if it ends with ok 1 verbose cli [ '/home/user/Downloads/node-v10.14.0-linux-x64/bin/n ...

Issue with running "ng generate" or "ng add" commands

While using angular version 8 in Termux Android ARM, I encountered an issue when trying to add the PWA and service worker to my website project. Here is the information about the angular version obtained from Angular CLI: $ ng version _ ...

Angular 5 introduces a bespoke directive that allows for element repetition within the framework

Looking to create a directive that contains an array of elements, and when the directive is bound to any element, that element will repeat the number of times equal to the length of the array. For example, if the array has 3 elements, the element will re ...