algolia / angular-instantsearch

⚡️Lightning-fast search for Angular apps, by Algolia
https://algolia.com/doc/deprecated/instantsearch/angular/v4/api-reference/instantsearch/
MIT License
261 stars 73 forks source link

Question: Is it possible to disable cache when using createSSRSearchClient? #961

Open MiguelAngelGarciaGomez opened 2 years ago

MiguelAngelGarciaGomez commented 2 years ago

We are using angular-instantsearch (v 4.1.0) in an Angular 13 application. In a component, we are retrieving the facets like:

async getFacetHits(attributeName: string) {
    const response = await this.config.searchClient
      .initIndex(this.config.indexName)
      .searchForFacetValues(attributeName, "*")
    return response.facetHits
  }

where this.config is:

this.config = {
      searchClient: createSSRSearchClient({
        appId: environment.applicationID,
        apiKey: environment.searchOnlyApiKey,
        makeStateKey,
        HttpHeaders,
        transferState: this.transferState,
        httpClient: this.httpClient,
      }),
      indexName: environment.indexName,
      routing: {
        router: ssrRouter(() => {
          if (this.request) {
            // request is only defined on the server side
            return this.request.url;
          }
          return window.location.pathname + window.location.search;
        }),
        stateMapping: simple(),
      },
    }

The method getFacetHits is called from the ngOnInit of the component to obtain some facets by their name. When we did this without using the createSSRSearchClient, using the regular algoliasearch it was working. But when we substituted it with the SSR version, it is obtaining the same results for every facet. So we suppose that, also according to the documentation, the request is cached. So we were wondering if the cache can be enabled. We have tried doing calling to await this.config.searchClient.clearCache() before the search is done, but the result is the same that without using it. We also have a look to the create-ssr-search-client-v4.spec.ts test, from the code, adding the line await ssrSearchClient.clearCache(); between the lines 121 and 122, for the test "will cache a repeated request", but nothing happens, the test passes. Are we doing something wrong? Or missing something?

UPDATE

We've found that the transferState object can be cleaned, something like:

const state = JSON.parse(this.transferState.toJson())
Object.keys(state).forEach((key) => {
    this.transferState.remove(makeStateKey<number>(key))
})

so the method looks like:

async getFacetHits(attributeName: string) {
    const state = JSON.parse(this.transferState.toJson())
    Object.keys(state).forEach((key) => {
      this.transferState.remove(makeStateKey<number>(key))
    })
    const response = await this.config.searchClient
      .initIndex(this.config.indexName)
      .searchForFacetValues(attributeName, "*")
    return response.facetHits
  }

But we are not sure if this is the best way to do it, or this can cause some side effects.

Haroenv commented 2 years ago

What I think is the issue here is that unlike the regular search requests done by InstantSearch, which use the method search and have all information in data, your method includes the facet name in the url, and thus isn't in data (the only item used for the cache key). There's a way to solve this by using searchClient.search([{ indexName: this.config.indexName, type: 'facet', params: { facetName: attributeName, facetQuery: '' }}]), as all cache data will be in "data" then and thus correctly cached