javascript - How can I include the Telegram login widget in an Angular app? - Stack Overflow

I want to include the Telegram login widget in my Angular application. For this, you have to include th

I want to include the Telegram login widget in my Angular application. For this, you have to include the following script:

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

Embedding scripts in Angular templates is not allowed, it will just be removed. (However, it is possible to include a script tag via this hack.)

Is there a non-hacky way of including this widget?

I want to include the Telegram login widget in my Angular application. For this, you have to include the following script:

<script async src="https://telegram/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>

Embedding scripts in Angular templates is not allowed, it will just be removed. (However, it is possible to include a script tag via this hack.)

Is there a non-hacky way of including this widget?

Share Improve this question edited Jun 1, 2019 at 16:06 Kim Kern asked Jun 1, 2019 at 14:17 Kim KernKim Kern 60.7k20 gold badges218 silver badges214 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

I created the following ponent for the Telegram login widget:

The ponent creates the script tag dynamically and adds 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.ponent.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/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();
  }

}

I added the callback function loginViaTelegram to the window object (global space) in 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));
  }
}

Not rendering script tags in template code is indeed a design choice from Angular team.

The way to do it is thus:

  1. Add your scripts to index.html - only relevant if it makes sense to load the script globally.
  2. Or Add your script programmatically. The post you refer to can be a solution, but brings in additional plication because it takes the input data from template code. A shorter solution is given here, when you're happy with inputing the parameters from the code-side (and the full issue is instructive too): Github issue #4903. Warning though: adding to the head is not suitable unless you remove it in OnDestroy. Prefer adding in the right DOM element of your ponent.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745223866a4617371.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信