I have been trying to integrate the AsyncTypeahead functionality from the react-bootstrap-typeahead library. I am trying to use this with the TheMovieDB search api. I can see from the developer console output that I am making the api requests successfully, and the results are being passed back into to the AsyncTypeahead component, but it is saying "No matches found." on my screen.
I have copied most of the code from their github for the AsyncTypeahead implementation, and can even see the reponse results are being passed down into the options the Typeahead
component. So I am unsure what I am missing to get them to be displayed on the screen like it is in their examples.
My search implementation component
import React from 'react';
import {AsyncTypeahead} from 'react-bootstrap-typeahead';
import axios from 'axios';
import SearchResultMenuItem from './SearchResultMenuItem';
//Needs to be a class based component, as we have to handle state
class SearchBar extends React.Component {
state = {
term: '',
options: [],
isLoading: false
};
onFormSubimit = (event) => { //Arrow function makes sure the value of 'this' is always the instance of the search bar
event.preventDefault(); //Stops browser from submitting form automatically and refreshing the pagee
this.props.onSubmit(this.state.term);
}
onHandleSearch = async (term) => {
this.setState({isLoading: true});
const response = await axios.get('https://api.themoviedb.org/3/search/movie?api_key=c055530078ac3b21b64e0bf8a0b3b9e1&language=en-US&page=1&include_adult=false', {
params: { query: term }
});
//Extract details from the search
const searchResults = response.data.results.map((i) => ({
title: i.original_title,
id: i.id,
}));
this.setState({
isLoading: false,
options: searchResults
})
}
render() {
return (
<div className="ui segment">
<form onSubmit={this.onFormSubimit} className="ui form">
<div className="field">
<label>Image Search</label>
<AsyncTypeahead
{...this.state}
labelKey="original_title"
isLoading={this.state.isLoading}
onSearch={this.onHandleSearch}
placeholder="Enter a Movie Title..."
renderMenuItemChildren={(option, props) => (
<SearchResultMenuItem key={option.id} item={option} />
)}
/>
</div>
</form>
</div>
);
}
}
export default SearchBar;
My SearchResultMenuItem component
import PropTypes from 'prop-types';
import React from 'react';
const SearchResultMenuItem = ({item}) => (
<div>
<img
style={{
height: '24px',
marginRight: '10px',
width: '24px',
}}
/>
<span>{item.original_title}</span>
</div>
);
SearchResultMenuItem.propTypes = {
item: PropTypes.shape({
original_title: PropTypes.string.isRequired,
}).isRequired,
};
export default SearchResultMenuItem;
Expected Results
I expect a list of movie names to be shown as options to choose, that come from the response from the query of TheMovieDB's api.
Actual Results
The UI simple displays a No matches found message on the screen.
I get a warning message on the console saying Warning: [react-bootstrap-typeahead] The prop id
is required to make Menu
accessible for users of assistive technologies such as screen readers. I have tried googling this, but have not found any solutions.
See below for screenshots from the developer console
You can see results from the search api in the options array above
Update UI After Fix
Please use labelKey="title"
in AsyncTypeahead since your options object has title.Also, in SearchResultMenuItem change <span>{item.title}</span>
, also change the props as well title: PropTypes.string.isRequired
. This should resolve the issue. Also, to remove the id warning just provide a unique id name to AsyncTypeahead component like id="some_unique_id"
(it can be any random id)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With