Reputation: 371
I have a problem with the data that I am fetching. I'm getting a uncaught in promise with my fetch call. That goes to say I also don't know if my code is even possible code or good code.
I have a filterbar where the user selects two dates, that means I put those input fields in a form, again not sure if I should do that, but that way I now have a onSubmit on my form. This onSubmit takes my function handleSubmit which calls my fetch.
import React, { Component } from 'react';
import { SplitButton, Dropdown, Container } from 'react-bootstrap';
import CarCard from '../components/results/CarCard'
//YYYY-MM-DD
class SearchBar extends Component {
state = {
fromDate: '',
toDate: '',
data: [],
}
handleSubmit = event => {
event.preventDefault();
this.getData()
}
handleChange = event => {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({ [name]: value });
}
getData = () => {
const { toDate, fromDate } = this.state
var url = 'https://www.fenonline.dk/SYS_Backend/api/car/'
url += fromDate + "/"
url += toDate
const data_promise = fetch(url).then(handleHttpErrors)
data_promise.then(data => this.setState({ data }))
}
render() {
return (
<Container>
<Container style={styles.container} fluid={true} >
<form onSubmit={this.handleSubmit}>
<h5 style={{ color: 'white', }}>Search for your rental here:</h5>
<input type="date" label="test" name='fromDate' onChange={this.handleChange} />
<input type="date" placeholder={this.state.toDate} name='toDate' onChange={this.handleChange} />
<input type='submit' value='search' />
</form>
</Container>
<Container>
{carCardItems(this.state.data) || 'Please wait...'}
</Container>
</Container>
);
}
}
export default SearchBar;
const carCardItems = data => {
const items = data.map(c =>
<CarCard key={c.regno} {...c} />
);
return items;
};
function handleHttpErrors(res) {
if (!res.ok) {
return Promise.reject({ status: res.status, fullError: res.json() })
}
return res.json();
}
Upvotes: 1
Views: 4853
Reputation: 447
Uncaught in promise means , an exception pops up somewhere, which is not handled (no catch block).
in this case inside getData, fetch needs a catch block. see below
const data_promise = fetch(url).then(handleHttpErrors).catch(error => {console.error(error);})
Upvotes: 0
Reputation: 30360
Perhaps you could rewrite getData()
using async/await
to better capture all possible code paths for uncaught errors/promises:
/* Define async function */
getData = async () => {
/* This try block will encapsulate the fetch logic, and capture all errors
that can be thrown */
try {
const { toDate, fromDate } = this.state
var url = 'https://www.fenonline.dk/SYS_Backend/api/car/'
url += fromDate + "/"
url += toDate
/* Use await instead of promise.then */
const response = await fetch(url)
/* The json() function is async, so use await */
const json = await response.json()
/* If response failed, return error data in same format as in your
Promise.reject() */
if(!response.ok) {
throw { status: response.status, fullError: json }
}
/* Update data with json */
this.setState({ data : json })
}
catch(error) {
/* Log error to console */
console.error(error)
}
}
Also note that response.json()
is an asynchronous method, which means you'll need to call it via await
as shown above (or as a promise; res.json().then(...)
). This means that doing:
return Promise.reject({ status: res.status, fullError: res.json() })
as shown in your code will mean the value of fullError
is a Promise
object, rather than the expected JSON data
Upvotes: 3