Within this series of posts I will go through the following steps:
- Displaying SharePoint data in the SPFx web part
- Creating a clickable zone within the web part
- Creating a form in an SPFx web part
- Displaying status update within the SPFx Web part
- Saving data from a form to SharePoint
- Updating fields within SharePoint (including choice, people, date and text fields)
In my previous post I introduced cleaning up the Hello World web part that you get when you get the SPFx Client Side web part using Yeoman.
In this post I’m going to create my base render web part and I’ll display some data fro SharePoint lists in my web part.
In SharePoint I have created a list (Bids) with the following fields:
- Title (Single line of text)
- PersonResponsible (Person/Group field)
- Urgency (Choice field with values of Low, Medium, High)
- ForecastClose ( Date Field)
I created a few more fields but within my posts I’m going to focus on these fields as they cover most of the common type of fields in SharePoint.
To support the data from SharePoint lists in my TypeScript code I’m creating an interface matching the lists fields, by creating a new file in my projects calls IBidTrackingBid.ts with the following content:
[code lang=text]
export interface Bid {
Id: Number;
Title: string;
PersonResponsible?: string;
PersonResponsibleId?: number;
ForecastClose?: Date;
Urgency?: string;
}
[/code]
To make my life a little bit easier I’m also adding an interface for a collections of bids.
[code lang=text]
export interface Bids {
value: Bid[];
}
[/code]
A couple of things to notice here.
- All the properties that end with a “?” postfix are optional fields.
- For my people field I’ve got a field matching my SharePoint name and I’m also using the Id property.
I will be using the REST API to get to my data and for people fields and choice fields I’m getting the item IDs returned.
Now within my web part class I’m adding two methods
[code lang=text]
private _getMockListDataBids(): Promise {
…
}
private _getListDataBids(): Promise {
…
}
[/code]
These 2 methods will get data from my mock data and from SharePoint. Note that both methods return my data in the same format. Both return a Promise of the type Bids.
Reading Mock data
To feed the above method with Mock data I’ve created a new file in my project MockBidTracking.ts. this mock data is used to test my web part while I’m not running the web part within a SharePoint environment
In the MockBidTracking I start with importing my bid interface.
[code lang=text]
import { Bid } from ‘./IBidTrackingBid’;
[/code]
Now I’m ready to create a new class.
[code lang=text]
export default class MockHttpBid {
}
[/code]
Within the above class I’m creating a private variable that holds my mock data
Then to get to my data from my web part I create a method to return my mockdata:
[code lang=text]
public static get(): Promise<Bid[]> {
return new Promise<Bid[]>((resolve) => {
resolve(MockHttpBid._items);
});
}
[/code]
now within my web part class I can add a method that reads the data from the mock store:
[code lang=text]
private _getMockListDataBids(): Promise {
return MockHttpBid.get()
.then((data: Bid[]) => {
var listData: Bids = { value: data };
return listData;
}) as Promise;
}
[/code]
Reading SharePoint Data
To read data from SharePoint I only need to call a REST API at : /_api/web/lists/GetByTitle(‘Bids’)/items and then return the JSON that is returned.
[code lang=text]
private _getListDataBids(): Promise {
return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + `/_api/web/lists/GetByTitle(‘Bids’)/items`, SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
return response.json();
});
}
[/code]
<h3>Rendering my Data</h3>
Now I’m adding another method to my Web Part class. This method will render my data independently from where the data comes from:
[code lang=text]
private _renderBidsAsync(): void {
// Local environment
if (Environment.type === EnvironmentType.Local) {
this._getMockListDataBids().then((bids: Bids) => {
this._renderBids(bids);
});
}
else if (Environment.type == EnvironmentType.SharePoint ||
Environment.type == EnvironmentType.ClassicSharePoint) {
this._getListDataBids().then((bids: Bids) => {
this._renderBids(bids);
});
}
}
[/code]
So if I use mock data or if I use SharePoint data in both cases this._renderBids(bids) will be called. Now we only need to implement
_renderBids and the data will be rendered to my page.
[code lang=text]
private _renderBids(bid:Bids): void {
let html:string = ”;
if (this._allBids) {
this._allBids.value.forEach((item: Bid) => {
html += ‘ … ‘ ;
});
}
const bidsContainer: Element = this.domElement.querySelector(‘#spBidsContainer’);
bidsContainer.innerHTML = html;
}
[/code]
In my next post will look at creating forms within my client side web part.
I hear you say: how do you now render the the data?
The html variable that is used above could be typically set to something like this:
[code lang=text]
html += `
<div class=”${styles.rowContainer}”>
<ul id=”bid_${id}” class=”${styles.bid}”>
<li class=”${styles.bidItem}”><span class=”${styles.bidTitle}”>${item.Title}</span>
<span class=”${styles.bidPerson}”>${initials}</span>
<span class=”${styles.bidPipelineStage}”>${item.PipelineStage}</span></li>
</ul>
</div>
`
<div class=”${styles.rowContainer}”>
[/code]
As there is a bit more to it than just normal html, I will address the details in a separate post.
I have based this series of posts on some of the work I’ve done for my customers. We have been looking at the new SharePoint framework since the early releases. If you would like to help us getting you started with SPFx then please feel free to contact me below.
your effort is good, but reading your blog through code is damn difficult, you should change your blog post with syntax highlighting in the code like Markdown syntax or something that helps readers.
Thanks for the feedback Luis, I’ve improved the formatting of this article a bit. I will look into using the Markdown options on WordPress.