What is the best way to integrate the Telegram login widget into an Angular application?

Does anyone know how I can integrate the Telegram login widget into my Angular application without resorting to hacks? The required script is as follows:

<script async src="https://telegram.org/js/telegram-widget.js?5"
  data-telegram-login="bot_name" data-size="large"
  data-auth-url="https://myurl.example/api/telegram"
  data-request-access="write"></script>

Angular does not allow embedding scripts directly into templates, but there may be a workaround like this suggestion. Is there a cleaner way to include this widget?

Answer №1

I developed a unique component specifically for integrating the Telegram login widget:

This component dynamically generates the script tag and includes the callback function loginViaTelegram(user):

@Component({
  selector: 'app-telegram-login-widget',
  template: `    
<div #script style.display="none">
  <ng-content></ng-content>
</div>`,
  styleUrls: ['./telegram-login-widget.component.css']
})
export class TelegramLoginWidgetComponent implements AfterViewInit {

  @ViewChild('script', {static: true}) script: ElementRef;

  convertToScript() {
    const element = this.script.nativeElement;
    const script = document.createElement('script');
    script.src = 'https://telegram.org/js/telegram-widget.js?5';
    script.setAttribute('data-telegram-login', environment.telegramBotName);
    script.setAttribute('data-size', 'large');
    // Callback function in global scope
    script.setAttribute('data-onauth', 'loginViaTelegram(user)');
    script.setAttribute('data-request-access', 'write');
    element.parentElement.replaceChild(script, element);
  }

  ngAfterViewInit() {
    this.convertToScript();
  }

}

To facilitate this process, I integrated the callback function loginViaTelegram into the window object (global space) using a dedicated service:

@Injectable({
  providedIn: 'root'
})
export class TelegramLoginService {    
  init() {
    window['loginViaTelegram'] = loginData => this.loginViaTelegram(loginData);
  }

  private loginViaTelegram(loginData: TelegramLoginData) {
    // If the login should trigger view changes, run it within the NgZone.
    this.ngZone.run(() => process(loginRequest));
  }
}

Answer №2

The decision not to include script tags in template code is a deliberate choice made by the Angular team.

To implement scripts, you have two options:

  1. Include your scripts in index.html - this is only necessary if the script needs to be loaded globally.
  2. Alternatively, add your script programmatically. While the solution mentioned may work, it adds complexity as it pulls data from the template code. A simpler approach, which involves inputting parameters from the code side, is provided here: Github issue #4903. Keep in mind that adding scripts directly to the head is not recommended unless removed in OnDestroy method. It's better to add scripts to the appropriate DOM element within your component.

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

Exploring the World of Html

I'm struggling with an HTML problem related to a web programming class I'm taking. The assignment involves creating a video game using HTML and JavaScript, where an image moves randomly on the screen and the player must click on it as many times ...

Implementing a boolean value in PrimeNG's p-dropdown version 7.x

I need a p-dropdown with two options to be selected based on the boolean value of the control. The control (NOTIF_ALL) is assigned a boolean value oldPendingTasksOptions=[ {"oldPendingTaskId": false, "oldPendingTasksName": "Not a ...

Is there a way to manipulate CSS to update automatically when new content is loaded via ajax?

I need help with customizing the CSS for 4 image links on my website. Each link is represented by a small image in its normal state and a larger image when hovered over. The content for each link is loaded using ajax. My question is how can I modify the C ...

Can you explain how I can showcase JSON object values within an Angular framework?

After fetching data through a REST API in Angular, I need to display only the "classLevelPermissions" in table format as shown in the .html file. .ts - async getclp(className: string) { debugger; this.clplist = []; this.className = className ...

Determining if a method's timeout has been triggered while running on a periodic basis in JavaScript

Within my JavaScript code, I have implemented a method that runs every 5 minutes. However, after 15 minutes, I want to stop this method from executing. var tChk ; tChk = setInterval("test()", 5*60*1000); setTimeout("timeOut(tChk)", 15*60*1000); // 15 mins ...

creating a Vuejs button function that will add together two given numbers

Help needed with VueJs code to display the sum of two numbers. Seeking assistance in developing a feature that calculates the sum only when the user clicks a button. Any guidance would be greatly appreciated! <!DOCTYPE html> <html lang="en"> ...

Ways to automatically close the external window upon logging out in Angular 12

I have successfully created an external window in my Angular application. Everything is working as expected, but I am facing an issue when trying to automatically close the external window upon user logout. Although I have written the code below and it wo ...

How can esbuild be used to load .wglsl files in Typescript files?

I'm currently utilizing esbuild to bundle my Typescript code, but I'm facing a challenge with configuring a loader for ".wgsl" files. Here is my app.ts file: import shader from './shader.wgsl'; //webgpu logic This is my shader.d.ts fi ...

Tips on storing a blob (AJAX response) in a JSON file on your server, not on the user's computer

After researching extensively on creating a URL from or downloading a blob in a computer, I require a unique solution: (1) Save a blob in own server into a JSON file, (2) Optimize the way to update a database using the data stored in the JSON. My attemp ...

Incorporating text onto an HTML webpage

Context: My program reads a file and displays it on an HTML page. The code below utilizes regex to extract errors from the file. Instead of using console.log for debugging, is there a way to display the results on the HTML page? When attempting: document ...

Having trouble utilizing Reactjs Pagination to navigate through the data

I'm currently working on implementing pagination for a list of 50 records, but I'm encountering an issue. Even though I have the code below, it only displays 10 records and I'm unaware of how to show the next set of 10 records until all 50 a ...

The Mongodb database is failing to recognize updates made to the Mongoose schema

I have already created my database with the following schema: const ProjectSchema = new mongoose.Schema({ name: { type: String }, description: { type: String }, client: { type: mongoose.Schema.Types.ObjectId, ref: 'client& ...

The custom created THREE.Curve is not rendering correctly

Following advice from this solution, I have implemented a linearly interpolated curve in the code below: THREE.Linear3 = THREE.Curve.create( function ( points, label /* array of Vector3 */) { this.points = (points == undefined) ? [] : points; ...

What steps should I take to resolve the "You do not have authorization to access this directory or page" error in Azure App Services?

Currently, I am attempting to deploy my Next.js 13 application to AppServices using Github Actions. The compilation process on Github was successful, however, I am encountering an issue where my application does not seem to be deploying or starting up prop ...

The static files for the icon CSS (404 Error) from Flaticon and Font-mfizz are failing to load properly

When I was designing a website, I needed an icon of Python, so I turned to Flaticon and found what I was looking for. This snippet shows the HTML code I used: {% load static %} <!DOCTYPE html> <html lang="en"> <head> <li ...

How can I add a string before a hashtag(#) in AngularJS URLs?

Can we add a prefix to the # symbol in angular.js URLs? For instance: let's say we have a site: http://example.com/ then when I click on the CSharp page, it redirects to http://example.com/#/csharp when I click on the AngularJS page, it redi ...

What is the best way to display a segment of an SVG on a Canvas element?

Main Issue: The main objective here is to display a specific part of an SVG image on a fixed size Canvas element within a web page. Approach I Tried: After considering various options, such as using CanVG, I thought about utilizing the viewBox attribute ...

Tips on avoiding quotation marks in a Less variable containing a color identifier

I'm currently working on an HTML/CSS project where I aim to establish classes for labels and texts based on their color. For instance: .text-red{ color: red; } .label-white{ color: white; } In order to achieve this, my approach involves cr ...

"Utilize jQuery to load a file when hovering over a specific

How can I dynamically load an external file using jQuery when a user hovers over a specific div? I attempted to load the file like a CSS file on hover but was unsuccessful. Is it possible to load a CSS file on hover as I've seen in some examples? $(d ...

Customer Notification System Malfunctioning on Front End

I am currently experimenting with MeteorJS technology and attempting to use alerts for success or failure notifications when making a meteor call. However, I've encountered an issue where the alerts are not functioning as expected. T ...