Search code examples
javascriptreactjsaxiostypeahead.jsreact-bootstrap-typeahead

React-Bootstrap-TypeAhead giving error when trying to change already selected option


So I'm using react-bootstrap-typeahead and it's working completely fine when I'm typing something in the search box. It gives me the relevant options when I type something in the search box like this:

enter image description here

However, when I select one of options and then try to re-change the text it throws an error. This is how it looks like when I select 1 option.

enter image description here

And this is the error it throws: TypeError: 'Cannot read property 'match' of undefined'

enter image description here

Here is the state of the Search component which has the Typeahead:

 class Search extends Component {
state = {
    hcpName: [],
    hcps: [],
    searchName: '',
    isLoading: false,
    hcp_id: 101,
    searchSelectedOption: ''
}

And here is the Typeahead I'm using:

   <div className='col-md-3'>
                    <div class="form-group">
                        <Typeahead
                            id="basic-example"
                            options={this.state.hcpName}
                            placeholder="Search by Name..."
                            emptyLabel={this.state.isLoading ?
                                <>
                                    <span>Searching...
                                        <Loader
                                            style={{ paddingLeft: '5px', display: 'inline' }}
                                            type="Circles"
                                            color="#0caf8d"
                                            height={15}
                                            width={20}
                                            radius={30}
                                        />
                                    </span>
                                </>
                                : ''}
                            isLoading={this.state.isLoading}
                            onInputChange={(searchName) => this.setState({ searchName }, () => {
                                {
                                    let nameValue = this.state.searchName;
                                    this.setState({ isLoading: true })
                                    axios.post('/get-hcp-data', {
                                        nameValue: nameValue
                                    })
                                        .then((res) => {
                                            const hcps = res.data;
                                            this.setState({ hcps: hcps, hcpName: Object.values(hcps.hcp_details_concat) })
                                            this.setState({ isLoading: false })
                                        }, (error) => {
                                            console.log(error);
                                        });
                                }
                            })}
                            onChange={(selectedOption) => {
                                console.log('selected option: ', selectedOption[0]);
                                console.log('npi id selected', selectedOption[0].replace(/(^.*\[|\].*$)/g, ''));
                                console.log('parsed npi id selected', parseInt(selectedOption[0].replace(/(^.*\[|\].*$)/g, '')[0]));
                                this.setState({hcp_id: parseInt(selectedOption[0].match(/[^[\]]+(?=])/g)[0])});
                            }}
                        />
                    </div>
                </div>

Inside 'onInputChange' inside Typeahead, I'm basically making an api call after every keystroke that a user enters. So that's why you can see an axios request over there. And inside 'onChange', I extract the number inside the square brackets of the user selection.

As I mentioned, I face an error when I try to change the text of the already selected option. For example, suppose I clicked on [101]Anna, I see that text in the search bar. And when I try to modify it again, I immediately see an error. What's the possible reason for this?

Here is the console log for onInput change:

enter image description here


Solution

  • I solved the problem by identifying that the match/replace function can't be used inside the onChange of Typeahead so I instead directly used it while fetching the api data. For that, I first set the state according to what the user has selected like this:

      onChange={(selectedOption) => this.setState({ searchName: selectedOption }, () => {
                                    console.log('selected option: ', selectedOption);
                                })}
    

    And then while fetching the data, I made use of the searchName state to run the replace function.

      dataFetch = () => {
        this.setState({ receivedData: [], loading: true });
        let page_id = this.state.page_id;
        let hcp_id = parseInt(this.state.searchName[0].replace(/(^.*\[|\].*$)/g, ''));
        axios.post('/test-json', {
            page_id: page_id,
            hcp_id: hcp_id
        })
            .then((res) => {
                this.setState({ receivedData: res.data, loading: false });
                console.log('State after loading data: ', this.state);
            }, (error) => {
                this.setState({ error: true });
                console.log(error);
            });
    }