React: Error Handling & Conditional Rendering
Error Handling
Continuing our sample application from the last post we are going to add error handling now. To start we declare another variable in this.state
called errorMessage
, and then we add that to the error callback on the geolocation function.
Then we add an error into our card in the render section.
class App extends React.Component {
// javascript class that initializes state
constructor(props) {
super(props);
this.state = { lat: null, long: null, errorMessage:'' };
window.navigator.geolocation.getCurrentPosition(
(position) => {
// we called setstate!
this.setState({
lat: position.coords.latitude,
long: position.coords.longitude,
});
},
(err) => {
this.setState({ errorMessage: err.message })
}
);
}
// react requires us to define render
render() {
return (
<div className="ui container">
<div className="ui card">
<div className="content">
<div className="header">Current Position:</div>
<div className="description">Latitude: {this.state.lat}</div>
<div className="description">Longitude: {this.state.long}</div>
<div className="description">Error: {this.state.errorMessage}</div>
</div>
</div>
</div>
);
}
}
And we can see that if we deny the location we get the error message on the screen.
The next step is that we don’t want this error field to be displayed all the time, because even if there isn’t an error we see this.
So we want to display this error div conditionally.
Conditional Rendering
We could of course handle this with basic if/else if/ else statements like this:
render() {
// if there is an error message and no position data
if (this.state.errorMessage && !this.state.lat) {
return (
<div className="ui container">
<div className="ui card">
<div className="content">
<div className="header">Current Position:</div>
<div className="description">Error: {this.state.errorMessage}</div>
</div>
</div>
</div>
)
// if there is no error message and there IS position data
} else if (!this.state.errorMessage && this.state.lat){
return (
<div className="ui container">
<div className="ui card">
<div className="content">
<div className="header">Current Position:</div>
<div className="description">Latitude: {this.state.lat}</div>
<div className="description">Longitude: {this.state.long}</div>
</div>
</div>
</div>
)
// if no error message and no position data
} else {
return (
<div className="ui container">
<div className="ui card">
<div className="content">
<div className="header">Current Position:</div>
<div className="description">Loading Location...</div>
</div>
</div>
</div>
)
}
}
}
This is not very DRY but it gets the job done.
To DRY this up we can create a simple component for the majority of this, called LatLongCard:
import React from "react";
const LatLongCard = (props) => {
return (
<div className="ui container">
<div className="ui card">
<div className="content">
<div className="header">Current Position:</div>
<div className="description"> {props.children} </div>
</div>
</div>
</div>
);
};
export default LatLongCard;
And then refactor the app using this component
render() {
// if there is an error message and no position data
if (this.state.errorMessage && !this.state.lat) {
return (
<LatLongCard>
<div className="description">Error: {this.state.errorMessage}</div>
</LatLongCard>
);
// if there is no error message and there IS position data
} else if (!this.state.errorMessage && this.state.lat) {
return (
<LatLongCard>
<div className="description">Latitude: {this.state.lat}</div>
<div className="description">Longitude: {this.state.long}</div>
</LatLongCard>
);
// if no error message and no position data
} else {
return (
<LatLongCard>
<div className="header">Current Position:</div>
<div className="description">Loading Location...</div>
</LatLongCard>
);
}
}
Comments
Recent Work
Basalt
basalt.softwareFree desktop AI Chat client, designed for developers and businesses. Unlocks advanced model settings only available in the API. Includes quality of life features like custom syntax highlighting.
BidBear
bidbear.ioBidbear is a report automation tool. It downloads Amazon Seller and Advertising reports, daily, to a private database. It then merges and formats the data into beautiful, on demand, exportable performance reports.