Skip to content

Instantly share code, notes, and snippets.

@sagrawal31
Last active January 26, 2024 13:22
Show Gist options
  • Save sagrawal31/76c089251008ac746fc8cf3aef4bc261 to your computer and use it in GitHub Desktop.
Save sagrawal31/76c089251008ac746fc8cf3aef4bc261 to your computer and use it in GitHub Desktop.
Alternative to Events which got removed in Ionic 5
import {Injectable} from '@angular/core';
import {Subject, Subscription} from 'rxjs';
/**
* A custom Events service just like Ionic 3 Events https://ionicframework.com/docs/v3/api/util/Events/ which got removed in Ionic 5.
*
* @author Shashank Agrawal
*/
@Injectable({
providedIn: 'root'
})
export class Events {
private channels: { [key: string]: Subject<any>; } = {};
/**
* Subscribe to a topic and provide a single handler/observer.
* @param topic The name of the topic to subscribe to.
* @param observer The observer or callback function to listen when changes are published.
*
* @returns Subscription from which you can unsubscribe to release memory resources and to prevent memory leak.
*/
subscribe(topic: string, observer: (_: any) => void): Subscription {
if (!this.channels[topic]) {
// You can also use ReplaySubject with one concequence
this.channels[topic] = new Subject<any>();
}
return this.channels[topic].subscribe(observer);
}
/**
* Publish some data to the subscribers of the given topic.
* @param topic The name of the topic to emit data to.
* @param data data in any format to pass on.
*/
publish(topic: string, data?: any): void {
const subject = this.channels[topic];
if (!subject) {
// Or you can create a new subject for future subscribers
return;
}
subject.next(data);
}
/**
* When you are sure that you are done with the topic and the subscribers no longer needs to listen to a particular topic, you can
* destroy the observable of the topic using this method.
* @param topic The name of the topic to destroy.
*/
destroy(topic: string): null {
const subject = this.channels[topic];
if (!subject) {
return;
}
subject.complete();
delete this.channels[topic];
}
}

1. Change the imports

Before

import {Events} from 'ionic-angular';

After

import {Events} from '../your/path/to/service/events';

2. Changes in the subscribe method

Before

events.subscribe('user:created', (user, time) => {
    console.log('Welcome', user, 'at', time);
});

After

this.events.subscribe('user:created', (data: any) => {
    console.log('Welcome', data.user, 'at', data.time);
});

3. Changes in the publish method

Before

this.events.publish('user:created', someUserInstance, Date.now());

After

this.events.publish('foo:user:logged-out', {
    user: someUserInstance,
    time: new Date()
});

4. To Unsubscribe

const subscription = this.events.subscribe('user:foo:created', (data: any) => {
    // your logic
});

Once you are done, you can do this-

subscription.unsubscribe();
@fromage9747
Copy link

Thanks! I will give it a bash!

@grantdevon
Copy link

Hi, Does someone perhaps know where I can find documentation on Unit testing this?

@johnwargo
Copy link

@grantdevon it's a Gist, a code sample; just a snippet of code, not a repo with tests, etc.
If you want unit tests, you're going to have to write them. :-)

@sagrawal31
Copy link
Author

Thanks @johnwargo for clarifying it for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment