Original post on Medium see here, code example in this article can be found in my Github Page.
In Part 1 we scaffolded a basic set up for our UK weather app and successfully fetched and displayed the weather data from Openweathermap API. An important point in part 1 was how user input data was stored in React state and sent to Node. You may have noticed that some errors happened when non-standard UK postcode was entered, thus in part 2 I’m going to show you my thoughts of handling these errors.
The error
Let’s take a look at what happens if entering a random postcode in the input field: aa123aa
The error is pretty much self-explanatory: response.result = undefined
. Console.log(response)
and we can see:
Openweathermap API returned a 404 error when a false postcode was entered.
How to handle the error?
Two possible issues could cause the error:
- The input postcode did not conform to UK format, e.g. qwerty;
- The input postcode conformed to UK format, but was not a valid UK postcode, e.g. aa123aa.
For 1, I’m going to add input validation using regex, for 2, I think there is no easy way to prevent a user from entering such postcode, so I’ll handle the error in getCoord
method before the address information is fetched.
1. Input validation using regex
When clicking the Search button, handleSubmit
method is called which also invokes getCoord
method. I add an error
state to store the validation status:
if(error === true) {
// show error message
}
else {
// remove error message
}
A very simple reminder message is placed next to he input field. In handleSubmit
method, the input is validated as follows: if valid, execute getCoord
and set error
state to false; else set error
state to true. The error message should be shown when error === true
, and hide when error === false
. Let take a look at Weather.js
:
You may have noticed that here in handleInputChange
method the error
state is set to false
. This is because if postcode is entered again, a user may already have noticed that he/she entered the wrong postcode, therefore the error message is removed immediately when the input state is changed (we don’t want to over-remind the user). Okay, so now the problem is how can we determine whether input is valid and run getCoord
? We could try to add some regex in handleValidation
method to address it.
Most UK postcodes follow a certain format thus implementing a regex myself to cover popular cases is possible, but if I want to cover all possible cases, doing it myself becomes infeasible quickly. I found a good solution in this popular Stack overflow answer, so the following code is added to handleValidation
method:
handleValidation() {
let regexConst = new RegExp('^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$');
return regexConst.test(this.state.postcodeInput);
}
As you can see, the regex pattern is very long, so I didn’t want to spend too much time on it and borrowed the Stack overflow answer. Let’s test it:
Good, now issue 1 is resolved. Issue 2 still persists: that is, if the input conforms UK postcode format and bypasses the regex, how can we handle the error?
2. Try {fetch API} catch {error}
From the console error we can see that the postcode API returned a 404 error, i.e. postcode not found. A simple try… catch statement can be used to catch the error and show the error message. The getCoord
method is updated as follows:
async getCoord() {
const postcodeAPI = `http://api.postcodes.io/postcodes/${this.state.postcodeInput}`;
let response;
try {
response = await fetch(postcodeAPI);
if (!response.ok) throw new Error('Weather api request failed.');
await response.json().then(response => {
this.setState({
addressData: response,
coordinate: [response.result.latitude, response.result.longitude]
});
let coord = {
latitude: this.state.coordinate[0],
longitude: this.state.coordinate[1]
}
axios.post('http://localhost:4001/search-location', coord)
.then((response) => {
console.log(response);
this.setState({
displayResult: true
});
}, (error) => {
console.log(error);
});
});
}
catch(e) {
this.setState({error: true});
console.log(e);
}
}
If an invalid postcode is passed to the API, the response object would contain a property ok = false
. Therefore this line is added: if (!response.ok) throw new Error(‘Weather api request failed.’);
to immediately cease the try statement and catch the error. In the catch
statement the error
state is set to true
such that the little reminder is shown next to the input field. Then the error is logged to the console with text ‘Weather api request failed’. No console error would be shown to the user. Let’s test it:
The 404 error in the console is default browser behaviour, so no need to worry about that. The try…catch statement threw the error and logged the message in the console, and the error
state made sure that the reminder was displayed.
What’s next?
Now that the errors are handled, one step closer to a good UK weather app. Obviously the app could look a bit prettier, so in the next article I will get the app decorated and show you how to do it.
Hope it helps! 😁
Top comments (1)
Hi thanks, such a great tutorial. What if I need to display the current weather of other cities, like not based on my current location but for other cities