Connected SharePoint Framework (SPFx) Webparts Part 2

The Other Webpart and the Communication Between the Two

So far, we have created a dropdown component that can be used as a child to some other component that can pass in a reference to a method the child can call on selection to perform whatever task for which the parent is being built, and put it all into a component. To arrive at our destination of having that webpart communicate the selected GitHub Id to another webpart that will display the repos for that Id, we only have to build out that other webpart, then add the communication into both of them.

The Repos Lister Webpart

To get started, from the tsx component generated when creating the project, I renamed the IGitReposProps to IGitReposPropsAndState, then in the component itself update the reference to the file and add a constructor. For now there are no state properties, so it is barebones. I also made some changes to the render method of GitRepos.tsx, including paying around with the office-ui styles, which one can review on the code on GitHub here. The key piece is this bit of markup:

<div className='ms-Grid'>
<ul className='ms-List ms-List--grid'
 id='reposList'
 ref='repos'
>
</ul>
</div>

This is where the repos will get listed out. Finally, thinking ahead, I know I will need to make an http call to GitHub, so I created added a property to the react component of type HttpClient, named httpClient, and pass in from the context of the webpart. Finally I added some console statements at key events of the react component lifecycle events.

At this point I ran the ‘gulp serve –nobrowser’ command to see it all in action with this result:

imageSo far, then, what we have is two webparts, one of which displays a dropdown that allows a selection, but does nothing else. The other of which does absolutely nothing. Now we have to add the communication piece using the built-in eventAggregator property of the webpart.


Adding Communication

Adding to GitIds (the event publisher)

To be able to publish an event for others to subscribe to, that is have connected SharePoint Framework (SPFx) webparts, the webpart component broadcasting the event needs to have an event aggregator to publish the event, which thankfully the the context of the BaseClientSiteWebPart provides. The other thing it will need is some sort of data structure to transmit whatever information the subscribers will need to perform their work. Under the src folder I have added a libraries folder with a single subfolder, EventData, which itself has a single file, EventData.ts. In their you will see three EventData types, one to pass on a single numeric value, another for a single text value, and another for a selected item value, with a string property, ‘selected’, and a numeric property ‘selectedIndex’. For our purposes we will use the EventDataSelected type to transmit.

For the event aggregator I added an IEventAggregator property named eventAggregator to the IGitIdsProps which required the following reference by adding the following reference to the file head:

import { IEventAggregator } from "@microsoft/sp-webpart-base/lib";

In the component class of the publisher, GitIds.tsx, you will also need this reference:

import { IEvent } from "@microsoft/sp-webpart-base/lib";

To effect the communication between the SPFx webparts, I added a method to publish the event, _broadcastData, that I call from the componentDidUpdate lifecycle event. Here is that code:

protected _broadcastData(): void {
this.props.eventAggregator.raiseEvent(
'GitIdEvent:start', {
data: {
selected: this.state.selected,
selectedIndex: this.state.selectedIndex
},
sourceId: 'GitIdWebPart',
targetId: 'GitReposLister'
} as IEvent<EventDataSelected>
);
}

Adding to GitRepos (the event subscriber)

To be able to subscribe to the event the GitRepos component will need two additional properties: eventAgregator (IEventAggregator; this needs the following reference ‘import { IEventAggregator } from "@microsoft/sp-webpart-base/lib";’) and subscriberId (string), so I added to the IGitReposProps. This get added to the webpart so:

const element: React.ReactElement<IGitReposProps> = React.createElement(
GitRepos,
{
description: this.properties.description,
httpClient: this.context.httpClient,
eventAggregator: this.context.eventAggregator,
subscriberId: this.context.instanceId
}
);

Additionally, we will be using state for the GitId upon which to act, so I added a string property named gitId, and I made sure to reference IGitReposState, along with the props, in the “class” header. The other references we will be needing are to our data types, the Http, and HttpClientResponse from ‘@microsoft/sp-http’ and IEvent from   ‘@microsoft/sp-webpart-base’:

import { EventDataSelected } from '../../../libraries/EventData/EventData';
import { IEvent } from '@microsoft/sp-webpart-base/lib';
import { HttpClient, HttpClientResponse } from '@microsoft/sp-http';

Now, for the GitRepos React component to recognize, and be able to respond to, the event coming from the GitIds component we will need the following line added to the constructor:

this.state = {
gitId: ''
};this.props.eventAggregator.subscribeByEventName("GitIdEvent: start", this.props.subscriberId, this.receivedEvent.bind(this));

Notice the the component subscribes to any event named GitIdEvent raised by an aggregator. The names Must match. Also there is a reference to the method _receivedEvent, which will handle the event, so must be implemented. I also added the comments from the SP PnP reference application about being able to also subscribe by SourceId and hope to add a third webpart that does so.

For now I am only going to display the event data in the GitRepos component to assure that the event is being properly raised by the GitIds component and recognized in GitRepos. This is done by setting the state in the_receivedEvent method, then displaying somewhere in the render method. after running using the ‘gulp serve’ command I can see the selected Id appear. Note that in the componentDidUpdate React lifecycle event I call the method _populateRepos that will actually get the repos for the selected Id then populate the list  accordingly. I do it this way in case there are any other state properties that need to be updated before making the http call. In this case I know there are not, but in a more complicated scenario this may come into play and introduce a difficult to trace bug. If you want to see the final code for ‘Connected SharePoint (SPFx) Webparts, you can see the code here.

One non standard thing I use in the render method is the ‘ref’ attribute, that I then reference. That is an item worthy of research and its own blog post.

No Comments

Add a Comment