Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aurelia Unsubscribe Event Aggregator

I am using Aurelia Framework with Typescript and in the event aggregator I am able to publish and subscribe to channels.

The problem is that I am unable to unsubscribe from a channel.

Note: All forms of the subscribe method return a dispose function. You can call this function to dispose of the subscription and discontinue receiving messages. A good place to dispose is either in a view-model's deactivate callback if it is managed by a router, or in its detached callback if it is any other view-model.

This is taken from the aurelia official documentation website and I don't really seem to understand how to implement this.

I went on the aurelia gitter channel and I found 3 discussions about this, where one of them gave the following example for unsubscribe:

sub = ea.subscribe();

//unsubscribe the event
sub();

The problem is that this code doesn't work in TypeScript.

How do I unsubscribe from an event aggregator in Typescript?

Now, using this code

    @inject(Publisher, Subscriber)
export class Home {
    publisher: Publisher;
    subscriber: Subscriber;
    channelName = "testChannel";

    constructor(pub: Publisher, sub: Subscriber) {
        this.publisher = pub;
        this.subscriber = sub;

        this.subscriber.subscribe(this.channelName);

        this.publisher.publish(this.channelName, "Ana are mere");
    }
}


@inject(EventAggregator)
export class Publisher {
    eventAggregator: EventAggregator = null;

    constructor(agg: EventAggregator) {
        this.eventAggregator = agg;
    }

    publish(channelName: string, object: Object) {
        this.eventAggregator.publish(channelName, object);
    }
}


@inject(EventAggregator)
export class Subscriber {
    eventAggregator: EventAggregator = null;

    constructor(agg: EventAggregator) {
        this.eventAggregator = agg;
    }

    subscribe(channelName: string) {
        this.eventAggregator.subscribe(channelName, object => {
            //TODO do something with received object
            alert(object);
        });
    }
    unsubscribe(channelName: string) {
        debugger;
    }
}

when executing the Home component, the method for subscribe isn't executed just once, but as many times as the cosntructor has been called. So, if I have been on the home page 3 times, it will get executed 3 times.

So: Why is my subscriber method fired multiple times ? How do I unsubscribe from event-aggregatoor in TypeScript?

Thanks!

like image 288
radu-matei Avatar asked Aug 25 '15 14:08

radu-matei


2 Answers

10/14/2015 EDIT

The EventAggregator class's subscribe function returns a "dispose" function "subscription" object:

var subscription = eventAggregator.subscribe('some event', value => alert(value));

You need to keep a reference to the subscription object so that you can destroy the subscription when it's no longer needed.

In a view-model, the perfect time to subscribe to an event is when it's attached. Likewise, a perfect time to unsubscribe is when it's detached.

Here's what your Home view-model would look like if it used this pattern (note: I've dropped your Subscriber and Publisher classes because I think they're adding unnecessary complexity around the EventAggregator and are making it hard to explain the solution to your issue).

@inject(EventAggregator)
export class Home {
  eventAggregator: EventAggregator;
  subscription: { dispose: () => void };

  constructor(eventAggregator: EventAggregator) {
    this.eventAggregator = eventAggregator;
  }

  attached() {
    this.subscription = this.eventAggregator.subscribe('some event', value => alert(value));
  }

  detached() {
    this.subscription.dispose();
  }
}
like image 112
Jeremy Danyow Avatar answered Oct 29 '22 06:10

Jeremy Danyow


You need to unsubscribe on deactivate()/detach(), as far as I'm aware using Typescript doesn't change this.

like image 29
Matt McCabe Avatar answered Oct 29 '22 04:10

Matt McCabe