Search code examples
reactivesearch

Submitting a search query with ReactiveSearch


I've been building a search UI with ReactiveSearch. I'm trying to figure out how to submit the actual search query. I've been using the DataSearch component because it comes with autocomplete baked in (just set it to true!). The autocomplete works fine. Suggestions are shown, I'm able to select them, BUT there are no actual search results when I select a suggestion by clicking on it or pressing enter.

Here is my DataSearch

<DataSearch
  placeholder="Search..."
  componentId="q"
  dataField={["firstname"]}
  queryFormat="or"
  className="navbar-search-box"
  icon={(<i className="fa fa-search fa-lg" style={searchIcon}></i>)}
  showIcon={true}
  iconPosition="right"
  URLParams={true}
  innerClass={{
    title: "text-title",
    input: "text-input",
    list: "text-item"
  }}
  react = {{
    "or": ["q"]
  }}
  onValueSelected={(value, cause, source) => {
    this.setState({redirect:true});
    }
  }
  onQueryChange = {
    (prevQuery, nextQuery) => {
    console.log('prevQuery', prevQuery);
    console.log('nextQuery', nextQuery);
    }
    }
    ...

I'm assuming I don't need to use their appbase-js library to submit a full-text search query to ES. I'm assuming the DataSearch component puts the query together as long as you have the dataField propery assigned a value.

I also get this error when I try to submit a query:

Warning: Each child in an array or iterator should have a unique "key" prop.

Maybe that has something to do with the search query not working? Not sure.


Solution

  • onQueryChange is fired any time a query changes for the component. Here you would have to check the cause in onValueSelected and then handle the updated query. For example:

    Demo

    <DataSearch
      ...
      onValueSelected={(value, cause, source) => {
        if (cause !== 'SUGGESTION_SELECT') {
          // use this.query
          console.log('use', this.query);
          this.setState({
            redirect: true
          });
        } else {
          this.valueSelected = true;
        }
      }}
      onQueryChange={(prevQuery, nextQuery) => {
        this.query = nextQuery;
        if(this.valueSelected) {
          // use this.query
          console.log('use', this.query);
          this.valueSelected = false;
          this.setState({
            redirect: true
          });
        }
      }}
    />
    

    Explanation

    When the cause for value selection is not a suggestion selection (i.e. it could be enter key press) then onQueryChange would have already updated this.query which you can use directly in onValueSelected. However, if the cause for value selection was SUGGESTION_SELECT, the query would have to update after selection. In this case I'm just setting a flag this.valueSelected, to delegate the query handling logic, which is then read in onQueryChange.

    In short for a suggestion selection, the flow goes from onValueSelected to onQueryChange and for other causes (including an enter key press), we would already have the query from onQueryChange in this.query, therefore it gets handled in onValueSelected. Hope this helps.

    As for sending a search request its not necessary to use appbase-js, a simple fetch request would also work. If you're using appbase-js then you could use the search method to just simplify the API docs.