I’m building a weather app and if the user inputs a non existent city name, no changes should occur in the app and the page should just throw an alert saying “city not found”. I tried doing this by attaching .catch(err => alert("City not found")), which was throwing the alert but the app was also crashing because the state was being set to an incompatible object. So now I added an if - else statement, which appears to do the trick, but I’m not sure if this is the best way to handle this. Here’s the link to full code https://codepen.io/Montinyek/pen/QWBEVmN
function getData(e) { // set state after searching
let name = event.target.value;
if (e.key === "Enter") {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${name}&appid=ba75f067791134427b7f0a23f45445e0
&units=metric`)
.then(response => response.json())
.then(data => {
if (data.cod !== "404") {
setToday(data)
let date = getDate(data.dt, data.timezone)
setToday(prev => ({...prev, "day": date.slice(0, 3), "date": date.slice(5, 16)}))
} else {
alert("city not found")
}
})
fetch(`https://api.openweathermap.org/data/2.5/forecast/daily?q=${name}&units=metric&cnt=7&appid=bc1301b0b23fe6ef52032a7e5bb70820`)
.then(response => response.json())
.then(data => {
if (data.cod !== "404") {
setDaily(data)
}
})
}
}
Within your if statement code block, why do you call setToday twice with different data? Why not just call it like the second time you do it?
Also, I would recommend not calling both fetch (they are basically getting called at the same time). If the city does not exist from the first url, wouldn’t not exist for the second call? Only call the second fetch if the first fetch does not result in a 404.
I don’t think I can achieve what I’m doing there without calling it twice. On the first call I get the data, then call the getDate function and use dt and timezone from data to get the date of the city being searched, and then I update today by calling setToday again and adding two additional keys - day and date.
Alright, I will put the second fetch in the if block. But is this an acceptable way of handling errors? I always thought a .catch was a must.
It would still add a catch to account for network issues. 400/500 errors will not throw an error, so you could do a return Promise.reject(error) within the catch to capture both network and HTTP errors.
Thanks. I have another issue right now. I just opened the app on my phone and it crashed after I typed a city name and pressed “search” on the keyboard. What could possibly cause this?
It just disappeared, which is what normally happens in Codepen when React crashes because of some internal error in the code. But it works fine on PC. Could you please try opening the link on your phone?
Everytime the value of input changes, you call getData. After the first letter, if it is not Enter, then nothing will happen. Codepen is reacting strangely to the issue. When I put on replit and add an extra else statement, so you can see what is going on.
You have at least two other errors showing in the browser console you also need to resolve.
I just noticed I had onChange={changeBg} on my input because I used that to console log some state values, but now I removed it from input completely. I checked the replit link and it looks like the issue arises on any key press. As for the other two errors, do you mean this? DevTools failed to load source map: Could not load content for chrome-extension://gighmmpiobklfepjocnamgkkbiglidom/browser-polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND
Also, can you point me in the direction of fixing these errors? I’m just not sure where to even look.
I changed it to onKeyPress and the issue seems to be resolved. Thank you. So could you please tell me what the other two errors might be? I’m just not seeing anything in the console other than that message in my previous reply.
Considering the keypress event is deprecated it might be better not to use it. Can’t you use onKeyUp instead? Or maybe switch to a form submit so you do not keep running the function on each key press (or maybe at least debounce it).
Not sure what the other errors are, other than the 404 you inviability will get with an invalid name.
Thank you, I’ll do that, but Randell said "You have at least two other errors showing in the browser console you also need to resolve.". I would really like to know what those errors are. I’m not seeing anything other than DevTools failed to load source map:
Great, thank you. One more question, are you getting a warning asking whether you want to continue when you hit enter in the input field? I’m wondering if it’s the way that I have my code set up that causes this, or it’s just a warning that CodePen itself issues.
That warning looks like something Codepen adds on.
FYI - You should never expose your api id. You should always use a proxy server to make a request to the api using the id and display the results to the client.