Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen to an external js event on angular app?

Tags:

I have a external js library on my angular app, I added it as a global script on the angular-cli.json scripts array. Its working fine, but I need to assign some functions as response to events of this library. This library has an Display object wich has some events:

Display.onplay
Display.onpause

How can I listen to these events in my angular component.ts ?

In plain javascript web application is just assign it to a function like:

  Display.onplay = function () { console.log('play'); }

But on angular i have no idea if its possible to do it.

like image 264
gog Avatar asked Jan 10 '18 19:01

gog


1 Answers

It is possible and appropriate to access external Javascript libraries from an Angular application. There are some issues to keep in mind however.

Type Declarations

I will get some compilation errors if I type just like that in typescript.

This is common in Typescript. There are a couple of ways to fix this issue.

The first (and likely best) approach is to include a Typescript type declaration (.d.ts) file for the Display library in your project. If this is a popular third-party library it may already be available as an npm package called @types/[PACKAGE_NAME]. If it is not available you can write a type declaration. More information about creating and including type declarations can be found in the Typescript Documentation.

The second approach is to simply use (Display as any).onplay or (Display as any).onpause to avoid compilation errors.

Unit Testing

Placing this code in your top-level component may suffice for your needs, but I doubt it. This restricts where the Display library can be used.

I suggest wrapping the library in a well designed service. Using a service allows the Display library to be accessed by multiple components/services.

You may be unit testing the code that relies on the Display library. If this is the case the appropriate place to use (Display as any).onplay = ... would definitely be in a service. Services make it easier to stub the functionality of the third-party libraries.

Here's an untested example service:

import { Injectable } from '@angular/core';

export interface IDisplayService {
    onPlay(callback: () => void): void;
    onPause(callback: () => void): void;
}

@Injectable()
export class DisplayService implements IDisplayService {
    private onPlayCallback: () => void;
    private onPauseCallback: () => void;

    constructor() {
        if (!Display) {
            throw new Error('Display library is required');
        }

        (Display as any).onplay = () => {
            if (this.onPlayCallback) { this.onPlayCallback(); }
        };
        (Display as any).onpause = () => {
            if (this.onPauseCallback) { this.onPauseCallback(); }
        };
    }

    // Using a function allows you to register multiple callbacks
    // if you choose to allow it later on.
    onPlay(callback: () => void): void {
        this.onPlayCallback = callback;
    }

    onPause(callback: () => void): void {
        this.onPauseCallback = callback;
    }
}
like image 59
Joe Hawkins Avatar answered Oct 13 '22 01:10

Joe Hawkins