Extract the event.data value from a window.addEventListener (MessageEvent) in order to trigger a separate function

Currently, I am delving into Angular and aiming to develop a LinkedIn Login API. To achieve this, I'm utilizing window.open to launch a new window where the user can either accept or decline the authorization. Upon successful acceptance, LinkedIn returns a code which is retrieved using window.addEventListener and event.data. This value is then sent to the parent window using window.opener.postMessage. However, the challenge lies in extracting this value from the addEventListener function to trigger another function with this value.

The component initiating the window popup where the LinkedIn login authorization is accepted or declined

import { Component, OnInit } from '@angular/core';
import { AuthService } from "../../services/auth.service";
import { ActivatedRoute }  from "@angular/router";

@Component({
  selector: 'app-sign-in',
  templateUrl: './sign-in.component.html',
  styleUrls: ['./sign-in.component.scss']
})
export class SignInComponent implements OnInit {
  private code:string;
  private state:string;

  constructor(
    public auth: AuthService,
    public route:ActivatedRoute
    ) { }


  //on initialisation we get the params and send the message to the addEventListener of the parent
  ngOnInit() {
    //get param of the URI specified in the LinkedIn URL
    this.code = this.route.snapshot.queryParamMap.get("code");
    this.state = this.route.snapshot.queryParamMap.get("state");
    if (this.code !== null){
      const params = window.location.search;
      if (window.opener) {
        //if the params exist then we send the code to the parent window
        if (this.state === this.auth.state) {
          // send them to the opener window
          window.opener.postMessage(this.code);
        }
      }
    } else if (window.opener){
      window.opener.postMessage('Authorization canceled');
    }
    window.close();
  }

}

The service where the window.open code is executed to retrieve the value from the child window to the parent window


    import { Injectable } from '@angular/core';
    import { Router } from '@angular/router';
    import {  HttpClient } from '@angular/common/http';

    //USER INTERFACE
    import { User } from './user.model';

    import { auth } from 'firebase/app';
    import { AngularFireAuth } from '@angular/fire/auth';
    import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';

    import { Observable, of, interval, Subscription } from 'rxjs';
    import { switchMap, take } from 'rxjs/operators';

    @Injectable({ providedIn: 'root' })

    export class AuthService {

      user$: Observable<User>;
      state: string = '';
      clientID: String = '';
      keyID: String = '';
      urlLinkedin = `https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${this.clientID}&redirect_uri=http://localhost:4200/authentification/sign-in&scope=r_liteprofile%20r_emailaddress%20w_member_social&state=${this.state}`;
      windowAttributes: string = "toolbar=yes,scrollbars=yes,resizable=yes,top=500,left=500,width=520,height=700";
      windowTarget: string = "_blank";
      codeRecup: string;
      
      constructor(
        private afAuth: AngularFireAuth,
        private afs: AngularFirestore,
        private router: Router,
        private http: HttpClient
      ) {

    //METHODS -------------------------------
     //LinkedIn ---------------------- 
    linkedinSignin(){
        window.open(this.urlLinkedin, this.windowTarget, this.windowAttributes);
        window.addEventListener('message',function(event) {
          if (event.origin !== "http://localhost:4200")
          return;
          console.log(event.data);
        },false);
      }

I aim to fetch event.data and utilize it in another function that will run after the window.addEventListener


    linkedinGetToken (){
      //I need to retrieve event.data in a new function that will be triggered after the addEventListener      
      this.codeRecup = event.data;
    }
     //End LinkedIn ----------------------

Answer №1

After discovering the solution, all credit goes to an insightful article I stumbled upon on StackOverflow: The key takeaway is to execute a function outside of the addEventListener to avoid using anonymous functions.


  //LinkedIn  ---------------------- 
    linkedinSignin(){
        window.open(this.urlLinkedin, this.windowTarget, this.windowAttributes);
        window.addEventListener('message', this.linkedinGetToken, false);
      }

    linkedinGetToken (event){
      if (event.origin !== "http://localhost:4200")
      return;
      console.log(event.data);
    }
     //End LinkedIn ----------------------

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

Connecting conversations in react

When working with jQuery, I often utilize the modal dialog chaining technique. For example: $.Deferred().resolve().promise() .then(function () { return runDialog1(someProps); // return promise }) .then(function (runDialog1Result) ...

Unable to inject service into Angular UseFactory Provider

After creating a generated API Client with Nswag and ASP Net Core, I needed to set the base URL for the client using the following code: export const BASE_API_URL = new InjectionToken<string>( "BASE_API_URL" ); @Injectable({ providedIn ...

Having trouble resolving modules after generating tsconfig.json?

I recently added a tsx component to my next.js 13 project following the documentation. After creating the required tsconfig.json file, I encountered module not found errors when running npm run dev: $ npm run dev > [email protected] dev > n ...

What is the most effective method of utilizing union or extend in TypeScript when faced with a comparable scenario?

I have a function that takes in two different types of objects: const canBeGenericOrDefaultData = { id: 123, pointData: { square: 'x145', triangle: 'y145' } } function submitHandler(canBeGenericOrDefaultData: AllTheDatas | G ...

The successful conversion of Typescript to a number is no longer effective

Just the other day, I was successfully converting strings to numbers with no issues. However, today things have taken a turn for the worse. Even after committing my changes thinking all was well, I now find that when attempting to cast in different ways, I ...

Issue encountered with express-jwt and express-graphql: TypeScript error TS2339 - The 'user' property is not found on the 'Request' type

Implementing express-jwt and graphql together in typescript has been a challenge for me. import * as express from 'express' import * as expressGraphql from 'express-graphql' import * as expressJwt from 'express-jwt' import s ...

Tips for centering an Angular mat prefix next to a label in a form field

Hey everyone, I need some help with aligning the prefix for an input with the mat label. Can anyone suggest a way to adjust the mat prefix so that it lines up perfectly with the mat label? Any assistance or ideas would be greatly appreciated. Here is the ...

service.js was identified as registered, however, it did not run as expected

I clicked on this link for my angular 2.0 tutorial journey. I managed to successfully display the list of drugs, but encountered an issue when I attempted to create the AuthorComponent. Unfortunately, my app stopped running due to the following error: Er ...

Show the values in the second dropdown menu according to the selection made in the first dropdown menu using Angular 8

My goal is to retrieve data and populate two dropdowns based on user selection. However, the code I've written isn't giving me the desired output and instead, errors are occurring. Being new to Angular, I would appreciate a review of my code. Her ...

Utilizing user input in API calls: A step-by-step guide

There is an input field where you can enter a city name to get the weather data for that specific city. Currently, I am using Angular 9 and able to display weather data for London only. // Updated Weather Components import {Component, OnInit} from ' ...

Fastify Schema Failing to Validate Incoming Requests

Currently, our backend setup involves using Node.js and the Fastify framework. We have implemented a schema in satisfy to validate user input. Below is the schema defined in schema.ts: export const profileSchema = { type: 'object', properti ...

Difficulty encountered when attempting to invoke a public function that makes use of a private function in TypeScript

I'm relatively new to TypeScript and I've been trying to replicate a pattern I used in JavaScript where I would expose functions through a single object within a module (like "services"). Despite my efforts, I'm facing some issues when attem ...

Error encountered while implementing onMutate function in React Query for Optimistic Updates

export const usePostApi = () => useMutation(['key'], (data: FormData) => api.postFilesImages({ requestBody: data })); Query Definition const { mutateAsync } = usePostApi(); const {data} = await mutateAsync(formData, { onMutate: ...

Proper positioning of try/catch block in scenarios involving delayed async/await operations

For the past six months, I have been utilizing async/await and have truly enjoyed the convenience it provides. Typically, I adhere to the traditional usage like so: try { await doSomethingAsync() } catch (e) {} Lately, I've delved into experimenti ...

What is the best way to loop through an object while keeping track of its value types

I have a JSON file containing UI adjustments sourced from the API: interface UIAdjustmentsJSON { logoSize: number; themeColor: string; isFullScreen: boolean; } To simplify things, let's utilize a static object: const adjustments: UIAdjust ...

The "ng2-CKEditor" package is experiencing compatibility issues with TypeScript in Angular 2

Currently, I am in the process of setting up CKEditor in my angular2 application. My backend platform is node.js and for this purpose, I am utilizing the ng2-CKEditor npm module. Below, you can find snippets from respective files. index.html:: <html& ...

Discovering the way to retrieve information from a service in Angular post-subscription

This is the service I provide: getDataDetails(id: any) { this.dataDocumment = this.afs.doc('data/' + id); return this.data = this.dataDocumment.valueChanges().subscribe(res =>{ this.data = res; console.log(this.data); ...

How can you determine if an API method call has completed in Angular and proceed to the next task?

Two methods are being used for api calls in my code. Method one is calling out method two and needs to wait for method two's api call to finish before continuing with its own process. I attempted to achieve this using the complete function inside a su ...

Which material design framework would be more suitable for my Angular 6 application - Angular Material or Bootstrap Material?

When starting my new Angular 6 application with Material Design, the big question arose: which material library should I use? Angular Material (https://material.angular.io/) Material Design for Bootstrap () Another option is the Bootstrap Material libr ...

Having trouble getting web components registered when testing Lit Element (lit-element) with @web/test-runner and @open-wc/testing-helpers?

Currently, I am working with Lit Element and Typescript for my project. Here are the dependencies for my tests: "@esm-bundle/chai": "^4.3.4-fix.0", "@open-wc/chai-dom-equals": "^0.12.36", "@open-wc/testing-help ...