The final topic in this chapter is how the React frontend consumes the backend web API. If the app isn't running, then run it by pressing F5 in Visual Studio. If we click on the Fetch data option in the top navigation bar in the app that opens in the browser, we'll see a page showing weather forecasts:
If we cast our minds back to earlier in this chapter, in the Understanding controllers section, we looked at the ASP.NET Core controller that surfaced a web API that exposed this data at weatherforecast. So, this is a great place to have a quick look at how a React app can call an ASP.NET Core web API.
The component that renders this page is in FetchData.js. Let's open this file and look at the constructor class:
constructor (props) {
super(props);
this.state = { forecasts: [], loading: true };
}
The constructor initializes some component state which contains the weather forecast data and a flag to indicate whether the data is being fetched. We'll learn more about component state in Chapter 3, Getting Started with React and TypeScript.
Let's have a look at the componentDidMount method:
componentDidMount() {
this.populateWeatherData();
}
This method gets invoked by React when the component is inserted into the tree and is the perfect place to load data. This method calls a populateWeatherData method, so, let's have a look at that:
async populateWeatherData() {
const response = await fetch('weatherforecast');
const data = await response.json();
this.setState({ forecasts: data, loading: false });
}
Notice the async keyword before the populateWeatherData function name. Notice also the await keywords within the function.
We can see that a function called fetch is used within this method.
The parameter that's passed into the fetch function is the path to the web API resource: weatherforecast. A relative path can be used because the React app and web API are in the same origin.
Once the weather forecast data has been fetched from the web API and the response has been parsed, the data is placed in the component's state.
Hang on a minute, though—the native fetch function isn't implemented in Internet Explorer (IE). Does that mean our app won't work in IE? Well, the fetch function isn't available in IE, but CRA has set up a polyfill for this so that it works perfectly fine.
Let's now turn our attention to the render method:
render () {
let contents = this.state.loading
? <p><em>Loading...</em></p>
: FetchData.renderForecastsTable(this.state.forecasts);
return (
<div>
<h1 id="tabelLabel">Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
{contents}
</div>
);
}
The code may contain concepts you aren't familiar with, so don't worry if this doesn't make sense to you at this point. I promise that it will make sense as we progress through this book!
We already know that the render method in a React component returns JSX, and we can see that JSX is returned in this render method as well. Notice the {contents} reference in the JSX, which injects the contents JavaScript variable into the markup below the p tag at the bottom of the div tag. The contents variable is set in the first statement in the render method and is set so that Loading... is displayed while the web API request is taking place along with the result of FetchData.renderForecastsTable when the request has finished, which we'll have a quick look at now:
static renderForecastsTable (forecasts) {
return (
<table className='table table-striped' aria-labelledby="tabelLabel">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
{forecasts.map(forecast =>
<tr key={forecast.dateFormatted}>
<td>{forecast.dateFormatted}</td>
<td>{forecast.temperatureC}</td>
<td>{forecast.temperatureF}</td>
<td>{forecast.summary}</td>
</tr>
)}
</tbody>
</table>
);
}
This function returns JSX, which contains an HTML table with the data from the forecasts data array injected into it. The map method on the forecasts array is used to iterate through the items in the array and render tr tags in the HTML table containing the data.
Notice that we have applied a key attribute to each tr tag. What is this for? This isn't a standard attribute on an HTML table row, is it?
Again, this is a lot to take in at this point, so don't worry if there are bits you don't fully understand. This will all have become second nature by the end of this book.