SharePoint Framework publish-subscribe event messaging


Communication between SPFx web parts through broadcasting events using the SPFx eventAggregator service.

Loosely coupled SPFx web parts through raising events to subscribers

Communication between the SPFx client side web parts through publish-subscribe events messaging has one big advantage, to make the components loosely coupled. That means few smaller SharePoint Framework web parts than one big monolith webpart. Because the functionality is split across smaller web parts the code base is smaller per web part so better extensibility and maintainability. Few SPFx web parts that can work as standalone, but also as composition on a SharePoint site page. See also Wikipedia on the publish-subscribe pattern. Velin Georgiev blog image

Here is a quick SharePoint Patterns and Practices (PnP) demo video:

Raise an event towards SharePoint Framework eventAggregator

Recently Miguel Rabaca from Spanish Point created SharePoint PnP sample (myself and Austin Breslin from Pramerica helped with polishing) that shows the out of the box SharePoint Framework eventAggregator service and how can be used to broadcast events to subscribers. Here is the sample link: SPFx Event Aggregator Sample
Please note the SPFx Event Aggregator is still in Alpha and NOT SUPPORTED IN PRODUCTION USE, but this sample will be updated in future when there are changes from the Alpha version to GA.
** The SPFx ReactiveX (RxJs) Event Emitter Sample sample may be used as temporary solution until the SPFx eventAggregator is generally available (GA). Here is how to use the SPFx Event Aggregator: Client side web part raises an event towards SharePoint Framework.

this.context.eventAggregator.raiseEvent(
      "myCustomEvent:start",
      {
        data: {  id: 1, name: "Velin Georgiev" },  // your data here
        sourceId: "BroadcasterWebPart", // string
        targetId: "ReceiverWebPart" // string
      } as IEvent<EventData>
    );
The SharePoint Framework will handle the messaging flow towards other web parts (subscribers) in the page. Client side web part can subscribe to events from the SharePoint Framework either using event name or by using instance identifier of event originator.

export default class Receiver extends React.Component<IReceiverProps, IReceiverState> {

  constructor(props: IReceiverProps) {
    super(props);

    // subscribe for event by event name.
    this.props.eventAggregator.subscribeByEventName("myCustomEvent:start", this.id, this.receivedEvent.bind(this));
  }

  /**
   * Method that handles Received event from the SPFx eventAggregator.
   * @param eventName the event name of the raised event.
   * @param eventObject the event object of the raised event.
   */
  protected receivedEvent(eventName: string, eventObject: IEvent<EventData>): void {
     ...
  }

Emit an event towards SPFx ReactiveX (RxJs) Event Emitter

I published another sample that shows how we can use the ReactiveX (RxJs) library with the SharePoint Framework to communicate between web parts through broadcasting events. Works in a similar fashion with the Event Aggregator, but the api is our custom implementation. Here is the sample link: SPFx ReactiveX (RxJs) Event Emitter Sample Emit event (broadcast message):

import { RxJsEventEmitter } from '../../../libraries/rxJsEventEmitter/RxJsEventEmitter';
import { EventData } from '../../../libraries/rxJsEventEmitter/EventData';
/**
 * Publisher (Observable) React component that broadcasts messages to Subscribers (Observers).
 */
export default class Broadcaster extends React.Component<IBroadcasterProps, IBroadcasterState> {

  private readonly _eventEmitter: RxJsEventEmitter = RxJsEventEmitter.getInstance();
  ...
  /**
   * Broadcasts data to all the subscribers.
   */
  protected broadcastData(): void {
    ....
    this._eventEmitter.emit("myCustomEvent:start", {  id: 1, name: "Velin Georgiev" } as EventData);
  }
Subscribe to an event
import { RxJsEventEmitter } from "../../../libraries/rxJsEventEmitter/RxJsEventEmitter";
import { EventData } from "../../../libraries/rxJsEventEmitter/EventData";

/**
 * Subscriber (Observer) React component that Receives broadcasted messages from Publisher (Observable).
 */
export default class Receiver extends React.Component<IReceiverProps, IReceiverState> {

  private readonly _eventEmitter: RxJsEventEmitter = RxJsEventEmitter.getInstance();

  constructor(props: IReceiverProps) {
    ...
    // subscribe for event by event name.
    this._eventEmitter.on("myCustomEvent:start", this.receivedEvent.bind(this));
  }

  /**
   * Method that handles Received event from the RxJsEventEmitter.
   * @param data the event object of the raised event.
   */
  protected receivedEvent(data: EventData): void {
     ...
  }

Conclusion

Both approaches and samples serve the same goal i.e. loose coupling and better maintainability. Both can be used in React, Angular, Knockoutjs or vanilla JavaScript/Typescript web parts. The SharePoint Framework eventAggregator will be the Microsoft recommended optionso keep an eye on it. Thanks to Miguel Rabaca from Spanish Point and Austin Breslin. Miguel created the sample with the SPFx event aggregator while I was working on the ReactiveX one, but myself and Austin refactored it to be testable.

Posted on

Tags: SharePoint SPFx Events, SPFx webparts communication, SPFx raise event, message broadcasting, SPFx pub-sub, SharePoint Framework Event Bus, Event Emitter, ReaxtiveX Js Observable Observer, RxJx Subject, RxJs lite,

Comments