My “world news webpart”. I don’t believe I did this. Learnt many things while developing this.
In this blog we will see how to connect to an external anonymous API from SPFX webpart. This webpart will display latest world news in it using office UI fabric controls (Document Card) and the no. of news count can be controlled through the webpart property pane
Step 1: Create SPFX React webpart
md Connectapi
cd Connectapi
Select “React” as framework while creating the webpart. Once the webpart is created open it with visual code
Step 2: Add fields to webpart property pane
We need to pass the external news API URL and the count of news from the webpart property pane, so let’s add a “Text” control and a “Slider” control into the property pane.
Open “ConnectapiWebPart.ts” file and add the below code into “getPropertyPaneCofiguration” method.
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
}),
PropertyPaneTextField('apiURL', {
label: "News API URL"
}),
PropertyPaneSlider('noofnews',{
label: "How many to show",
min: 2,
max: 10,
value: 2,
showValue: true,
step: 2
})
]
}
]
Declare them in props interface and set property control values to props so that we can pass the values entered in webpart property pane
export interface IConnectapiWebPartProps {
description: string;
apiURL: string;
noofnews: number;
}
public render(): void {
const element: React.ReactElement<IConnectapiProps > = React.createElement(
Connectapi,
{
description: this.properties.description,
noofnews: this.properties.noofnews,
apiURL: this.properties.apiURL
}
);
ReactDom.render(element, this.domElement);
}
Step 3: Connect to external news API
For this blog I have used “newsapi”, its free. You need to register and “Get API Key”. Don’t worry its quick and easy less than a minute.
Open “Connectapi.tsx” file and create a interface making all parts of one news panel
export interface ITrendingDocument{
title: string;
description: string;
url: string;
previewImageUrl: string;
}
Create another interface to declare state elements
export interface IConnectapiState{
trendingDocumentss: ITrendingDocument[];
title: string;
description: string;
url: string;
urlToImage: string;
}
Initialize state using a constructor inside default class
constructor(props: IConnectapiProps, state: IConnectapiState){
super(props);
this.state = { trendingDocumentss: [] as ITrendingDocument[], title: null, description: null, url: null, urlToImage: null};
}
Now add the actual code which will retrieve data from the news API using fetch operation
private getTrendingNews(_URL: string): void{
fetch(
_URL,
{
method: 'GET',
credentials: 'same-origin',
headers: {
'accept': 'application/json'
}
}
).then(response => {
return response.json();
}).then(json => {
var trendingDocumentss: ITrendingDocument[] = [];
if(json.articles.length>0)
{
for(var i=0;i<this.props.noofnews;i++){
trendingDocumentss.push({
title: json.articles[i].title,
description: json.articles[i].description,
url: json.articles[i].url,
previewImageUrl: json.articles[i].urlToImage
});
};
this.setState({trendingDocumentss});
}
}).catch(e => {
console.log(e);
});
}
The above method will be called before render using “componentDidMount”. So, add the below code.
public componentDidMount():void{
this.getTrendingNews(this.props.apiURL);
}
We need the same method to be called whenever we change the news count in the slider, so call it in “componentDidUpdate”
public componentDidUpdate(prevProps: IConnectapiProps, prevState: IConnectapiState, prevContext: any): void {
if (this.props.noofnews !== prevProps.noofnews) {
this.getTrendingNews(this.props.apiURL);
}
}
We are ready with the data retrieval part. Let’s move on to how to display them in the webpart.
Step 4: Add Office UI fabric Document Card
npm install office-ui-fabric-react
For more details refer Microsoft site here
Add below import statements in ‘Connectapi.tsx’
import {
DocumentCard,
DocumentCardPreview,
DocumentCardTitle,
} from 'office-ui-fabric-react/lib/DocumentCard';
public render(): React.ReactElement<IConnectapiProps> {
const newslist: JSX.Element[]= this.state.trendingDocumentss.map((doc:ITrendingDocument)=>{
return <DocumentCard onClickHref={doc.url}>
<DocumentCardPreview previewImages={[
{
previewImageSrc: doc.previewImageUrl,
width: 318,
height: 196,
accentColor: '#ce4b1f'
}
]} />
<DocumentCardTitle title={doc.title} />
<DocumentCardTitle title={doc.description} shouldTruncate showAsSecondaryTitle/>
</DocumentCard>
})
return (
<div className={ styles.connectapi }>
{ newslist}
<div style={{clear: 'both'}}/>
</div>
);
}
One last thing I also added the css into “Connectapi.module.scss” so that to fit 2 images in one row.
[class*='ms-DocumentCard '] {
float: left;
margin: 0.5em;
}
Ready to go. Hit Gulp serve. Add the webpart in the local workbench. Edit property to open webpart property pane and add the below news api URL in “News API URL” field in webpart property
“https://newsapi.org/v2/top-headlines?country=gb&apiKey=insertyourkeyhere”

Its great to see my world news webpart loading. Thanks for reading my blog. #sharingiscaring. Referred Walkdek blog which helped me a lot.
