Search code examples
algoliainstantsearch.jsinstantsearch

change searchFunction dynamically


context: I'm trying to implement multiples indexes binding to just one searchbox

I have an array of indexes and I want to edit the searchFunction of first one.

const indexes = indexNames.map( name => return createAlgoliaIndex(name) )
const main = indexes[0]

main.searchFunction = (helper) => {
  indexes.forEach( (algoliaIndex, index) => {
    if (index === 0)
      return;

    algoliaIndex.helper.setQuery(helper.state.query).search()
  })

  helper.search()
}

createAlgoliaIndexFor(name) {
  return instantsearch({
    indexName: name,
    searchClient
  })
}

Basically it doesn't work :(

any ideas?


Solution

  • You apparently do not have the choice: the searchFunction option must be passed at initialization time.

    Here's a working example (sorry the code is a bit messy):

    const searchClient = algoliasearch('1KCCSVLJHD', '0fb99058412c4776c60725c0fe9b2d7d');
    
    const indexes = ["test", "test2"].map((name, idx) => {
      const searchFunction = idx !== 0 ? null : (helper) => {
        indexes.forEach((algoliaIndex, index) => {
          if (index === 0) {
            return;
          }
    
          algoliaIndex.helper.setQuery(helper.state.query).search()
        });
    
        helper.search();
      };
    
      return instantsearch({
        indexName: name,
        searchFunction,
        searchClient
      })
    });
    
    
    indexes[0].addWidget(instantsearch.widgets.searchBox({
      container: '.search-box'
    }));
    indexes[0].addWidget(instantsearch.widgets.hits({
      container: '.hits-1'
    }));
    indexes[1].addWidget(instantsearch.widgets.hits({
      container: '.hits-2'
    }));
    
    
    for (var i = indexes.length - 1; i >= 0; i--) {
      indexes[i].start();
    }
    <script src="https://cdn.jsdelivr.net/npm/algoliasearch@3.32.1/dist/algoliasearchLite.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@3.2.0"></script>
    <div class="search-box"></div>
    
    <h1>First index</h1>
    <div class="hits-1"></div>
    
    <h1>Second index</h1>
    <div class="hits-2"></div>

    It's basically what you're doing, but the searchFunction is passed directly to the instantsearch initialization function, only for the first (main) index.

    Note that because calling start on an instantsearch instance will immediately call search and hence the searchFunction, you have to start the main instance last so that helper exists on the other instances.