2

I have a third party chat library, Which I imported in index.html as

<script type="text/javascript" src="/thirdPartyChatLibarary"></script>

This library broadcast events as chat-started, chat-ended etc.

I have captured the same events in my AngularJs-v1.6 project on broadcast as

scope.$on('cobrowse.linkClicked', callFunction());

I need to capture same events in my Angular-v7.0+ project.

I knew of eventEmitter and @input property but those will connect child to parent , here I have event broadcasting from third party.

I am not very sure if Observable from rxjs may help.

Is there any equivalent of $on in angular which can capture these events globally?

Mayank
  • 934
  • 1
  • 17
  • 37
  • This question is a little vague, but in general I'd recommend against global imports in favor of installing an npm module. Then, import it only in the component where you need it. Is the chat library published on npm? – Keenan Diggs Feb 15 '19 at 21:04
  • No its not published on npm, i have just use it through script tag , I have two projects, one works on angularjs1.3 where i am able to get it on $on while second one is in angularjs7.0 . chat library in immutable – Mayank Feb 15 '19 at 21:08

2 Answers2

3

I would like to share some of the methods I have tried.

Lets first discuss the ways we can broadcast and listen events within application that I have tried first.

A) events broadcast-receive within application

1) With host property of @componet e.g

 @Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  host: {
    "(document:click)": "onDocumentClicked($event)"
  }
})
export class AppComponent {
  onDocumentClicked(ev) {
    console.log("clicked", ev);
  }
}

2) with @HostListener

import { HostListener, Component } from "@angular/core";

add function and listener as

@HostListener("document:click", ["$event"])
  onDocumentClicked(ev) {
    console.log("clicked", ev);
  }

3) Observables from rxjs

Create service as

import { Injectable } from '@angular/core';
import { from, Subject } from 'rxjs';

@Injectable()
export class ListnerAndBroadcast {
    listeners: any;
    eventsSubject: any;
    events: any;

    constructor() {
        this.listeners = {};
        this.eventsSubject = new Subject();

        this.events = from(this.eventsSubject);

        this.events.subscribe(
            ({name, args}) => {
                if (this.listeners[name]) {
                    for (let listener of this.listeners[name]) {
                        listener(...args);
                    }
                }
            });
    }

    on(name, listener) {
        if (!this.listeners[name]) {
            this.listeners[name] = [];
        }

        this.listeners[name].push(listener);
    }

    off(name, listener) {
        this.listeners[name] = this.listeners[name].filter(x => x != listener);
    }

    broadcast(name, ...args) {
        this.eventsSubject.next({
            name,
            args
        });
    }
}

Now we need to broadcast event from any child component

this._ListnerAndBroadcast.broadcast('myCustomEvent', 'event');

In my case I have broadcasted the same from my deepest component footer.

and receiving it on root component as

this._ListnerAndBroadcast.on('myCustomEvent', (event) => {
      console.log('myCustomEvent received '+ event);
    }); 

Personally I like above approach as it can be dynamic and can handle any stream of events.

B) event received from third party or out of application

I have used Renderer2

as

In child component add as

import { Component, Renderer2 } from '@angular/core';

renderer2.listen('document', 'myCustomEvent', (evt) => {
      console.log('getting it from renderer ', evt);
    })

Now we need to broadcast event .

so to mimic third party events service , run following code in browsers console

var event = new CustomEvent(
      'myCustomEvent',
      { detail: { 'param1': 1, 'param2': 2 } }
    );
    document.dispatchEvent(event);

You would be able to see the results in console .

I am using angular 7+ and rxjs 6.2

links helped me to learn just consolidated all the solution above

Global Events and Event Delegation

Global event listener with observable

Thanks !

Mayank
  • 934
  • 1
  • 17
  • 37
0

You could possibly use the fromEvent operator that RxJS provides. Check out an example here. This operator is pretty self-explanatory! It creates an Observable from an event.

Zachary Bennett
  • 932
  • 9
  • 15