Introduction
In this article, I'm going to build the Home page of the application.
It will display the list of all the available seasons of the competition Serie A.
Setting up axios
To make HTTP calls I have two options: fetch
or axios
. For this article I choose to pick up axios
npm install axios
Once installed, I create a new module, httpService.ts
import axios from 'axios';
const httpService = axios.create({
baseURL: 'http://api.football-data.org',
timeout: 1000,
headers: {
'X-Auth-Token': 'FOOTBALL DATA API KEY', // your account API Key
},
});
export default httpService;
This module exports an axios configuration
that we can use throughout the application. Using this configuration I don't have to write every time same things like headers
or the timeout
of the request.
The Home
component
In the first place, I'd like to take the Home component out from Routes.tsx
.
import React, { Component } from 'react';
import {
Container,
Grid,
} from '@material-ui/core';
interface IProps {};
interface IState {
matchday: number,
matches: any[],
competition: any,
error: boolean,
totalMatchdays: number,
};
class Home extends Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
matchday: 1,
matches: [],
competition: null,
error: false,
totalMatchdays: 38,
};
}
render() {
return (
<Container>
Home
</Container>
);
}
};
Now, using httpService
I can fetch data.
...
import httpService from '../../../services/httpService';
import { AxiosResponse } from 'axios';
...
fetch = () => {
httpService
.get(`/v2/competitions/2019/matches?matchday=${this.state.matchday}`)
.then((response: AxiosResponse) => {
this.setState({
competition: response.data.competition,
matches: response.data.matches,
});
})
.catch((error: AxiosResponse) => {
this.setState({ error: true });
});
};
This function has to be called everytime the state changes and the component is re-rendered: componentDidMount
.
componentDidMount() {
this.fetch();
};
Adding some console.log
I can see the response in the browser console
Now that I have the complete response, I can add more specific interfaces to my IState
.
interface ICompetition {
id: number;
area: object;
name: string;
code: string;
plan: string;
lastUpdated: string;
};
interface IScore {
winner: string;
duration: string;
fullTime: {
homeTeam: number | null;
awayTeam: number | null;
};
halfTime: {
homeTeam: number | null;
awayTeam: number | null;
};
extraTime: {
homeTeam: number | null;
awayTeam: number | null;
};
penalties: {
homeTeam: number | null;
awayTeam: number | null;
};
};
interface ITeam {
id: number;
name: string;
};
interface IReferee {
id: number;
name: string;
nationality: string | null;
};
interface IMatch {
id: number;
season: object;
utcDate: string;
status: 'SCHEDULED' | 'LIVE' | 'IN_PLAY' | 'PAUSED' | 'FINISHED' | 'POSTPONED' | 'SUSPENDED' | 'CANCELED';
matchday: number;
stage: string;
group: string;
lastUpdated: string;
score: IScore;
homeTeam: ITeam;
awayTeam: ITeam;
referees: IReferee[];
};
interface IState {
matchday: number,
matches: IMatch[] | [],
competition: ICompetition | null,
error: boolean,
totalMatchdays: number,
};
Displaying matches details
I can now access these information from the state
<ul>
{matches.map((match: IMatch) => (
<li key={match.id}>
{match.homeTeam.name} <b>{match.score.fullTime.homeTeam}</b> - <b>{match.score.fullTime.awayTeam}</b> {match.awayTeam.name}
</li>
))}
</ul>
The list I obtain is the following.
For now, this component is limited because I can display only matches of the first matchday. But what if I want to choose the matchday I'd like to display?
Updating the list when state changes
I create a new function
handleChange = (event: any) => {
this.setState({ matchday: event.target.value }, () => {
this.fetch();
});
};
This handler fetches date from the APIs everytime is called.
Then, I add a new element in the UI: a select
.
render() {
const options = [];
for (let index = 1; index <= this.state.totalMatchdays; index++) {
options.push(<option key={index}>{index}</option>)
}
...
<select onChange={this.handleChange} value={this.state.matchday}>
{options}
</select>
Everytime this select
changes, the state is popoluated with new macthes of a different matchday.
Conclusion
Now that I added a basic functionality to the Home component, I can think how to improve it.
For example, the select
can be replaced by the Material UI Select
component https://material-ui.com/components/selects/; the ul
can be improved by using Material UI Card
component https://material-ui.com/components/cards/.
Top comments (0)