Trouble with eventAggregator when using slightly more complicated implementation


#1

I am trying to implement a simple messaging system where a div resides at the top of the page and it has one viewmodel called messages.

I followed THIS (Eric L. Anderson’s tutorial on the eventAggregator) tutorial but mine is a little different and is error-ing.

The viewmodel is called messages - first the template:

        <template>
            message: ${message}
            alertType: ${alertType}
        </template>

Here is the typescript file’s contents:

import { Aurelia, PLATFORM, autoinject } from "aurelia-framework";
import { EventAggregator } from 'aurelia-event-aggregator';

@autoinject
export class Messages {
  public alertType: string;
  public message: string;

  constructor(private eventAggregator: EventAggregator) {

    this.eventAggregator.subscribe(MessagePayload, (publishedMessage, alertType) => {
        this.message = publishedMessage;
        this.alertType = alertType;
    });

};

As you can see the constructor has the subscribe function. “MessagePayload” is the class that can be instantiated. It goes to a function that takes two parameters.

This is “MessagePayload” - has two variables in its constructor.

    export class MessagePayload {
        alertType: string;
        message: string;

        constructor(message: string, alertType: string) {
            this.message = message;
            this.alertType = alertType;
        }

    }

I am publishing from a manual button for the moment and the function bound to that button is this:

secondTestAggregator() {
    this.eventAggregator.publish(new MessagePayload("Updated test message", "success"));
}

I am getting an error on this publish line:

scheduler.ts:35 Uncaught TypeError: Cannot set property ‘message’ of undefined
at Scheduler.app/components/scheduler/scheduler.Scheduler.secondTestAggregator (scheduler.ts:35)

I dont know why this is not working and wonder if someone might point out the reason why?


#2

From your post it looks like MessagePayload is a class/method and not a channel (string).

According to their docs, http://aurelia.io/docs/fundamentals/cheat-sheet#the-event-aggregator, you’ll need first a string which represents the channel, then your payload.

So…

this.eventAggregator.subscribe('my-event-channel-name', (publishedMessage, alertType) => {
        this.message = publishedMessage;
        this.alertType = alertType;
    });

then…

secondTestAggregator() {
    this.eventAggregator.publish('my-event-channel-name', new MessagePayload("Updated test message", "success"));
}

#3

Thank you that now works…


#4

For completeness sake, the channel doesn’t need to be a string. It can be a function or anything really. The only issue with his code is that he wasn’t specifying the channel in the publish. This would work fine though:

this.eventAggregator.publish(MessagePayload, new MessagePayload("Updated test message", "success"));