Refinement doesn't happen when I keypress the first letter using the autocomplete widget

I am using autocomplete widget with Angular, I have based on this example https://codesandbox.io/s/loving-haibt-mcwie?file=/src/app/autocomplete.component.ts,
if I write a word the search is done up to the penultimate letter, I must write the word twice so that it works.

I attach a little code.

// component.Html
<input type="text" #destination (keyup)="handleChange($event)" (keyup.enter)="keyupEnter($event)" placeholder="¿A dónde?" autocomplete="null"/>
  <hr/>
    <div *ngFor="let index of state.indices">
      <div class="row" *ngFor="let option of index.hits" (click)="onOptionSelection.emit(option)">
        <span class="icon" [ngSwitch]="option.location_type">
          <i class="fas fa-city" *ngSwitchCase="'city'"></i>
          <i class="fas fa-flag" *ngSwitchCase="'country'"></i>
          <i class="fas fa-globe-europe" *ngSwitchCase="'continent'"></i>
          <i class="fas fa-globe" *ngSwitchDefault></i>
        </span>
        <p class="text">
          <span class="name">{{ option | nameByLang: locale }}</span>
          <span class="extra" *ngIf="option.country">{{ option.country | nameByLang: locale }}</span>
        </p>
      </div>
    </div>

// component.Ts
......
changeDetection: ChangeDetectionStrategy.OnPush
......
state: {
    query: string;
    refine: Function;
    indices: any[];
  };
  destinationWord = '';

  constructor(
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchParent,
    @Inject(LOCALE_ID) public locale: string
  ) {
    super("OriginAutocompleteComponent");
  }

  public ngOnInit() {
    this.createWidget(connectAutocomplete, {});
    super.ngOnInit();
  }

  ngAfterViewInit() {
    this.inputDestination.nativeElement.focus();
  }

  public handleChange($event: KeyboardEvent) {
    this.destinationWord = ($event.target as HTMLInputElement).value + ' ';
    this.state.refine(this.destinationWord);
  }
  keyupEnter($event) {
    this.onOptionSelection.emit(this.state.indices[0].hits[0]);
  }

Can you reproduce the behavior you currently have by forking this sandbox? It’ll be easier to help you achieve the expected result.

In this sandbox I reproduce the problem (https://codesandbox.io/s/flamboyant-bash-9xkcr).
Additionally I want to filter by a hit type that I receive, I have placed the filter in the html with * ngIf, how should I do it from the component side, is in the searchFunction ?, if you can put a simple filter in the responses (something type option.name.lenght > 5)

You don’t seem to follow the initial sandbox since you don’t use the same technique, leveraging connectAutocomplete. I’d recommend starting from there.

Regarding your second question, can you provide what you have so far?

I started from the initial Sandbox, eliminate the unnecessary and added the OnPush strategy in automcomplete … ts and app.component.ts. If you look at the autocomplete component you will see this.createWidget (connectAutocomplete).

My code is very similar to that of the Sandbox except that by adding style classes, we receive options in the hits, and those options have properties such as the name, I have a type property in my results, and I just want to show the results of a certain type.
my code in the html is as follows:

<ng-container *ngFor="let option of index.hits">

// HERE IS THE FILTER, I WANT THE FILTER IN THE COMPONENT
<div class=“row” *ngIf=“option.location_type == ‘city’” (click)=“onOptionSelection.emit(option)”>

          <span class="icon">

            <i class="fas fa-city"></i>

          </span>

          <p class="text">

            <span class="name">{{ option | nameByLang: locale }}</span>

            <span class="extra" *ngIf="option.country">{{ option.country | nameByLang: locale }}</span>

          </p>

      </div>

    </ng-container>

Hi @juanjco2

Please look at the example above I just made.
From autocomplete.component.ts,

            (click)="onQuerySuggestionClick.emit(hit)"

It passes the whole hit object.

And in app.component.ts,

  public setQuery(hit) {
    console.log({ hit });
    this.searchParameters = {
      query: hit.name,
      facetFilters: ["brand:" + hit.brand]
    };
  }

It uses the information from the hit and apply query and facetFilters.
Is it what you intend to do?
Please correct me if I don’t understand correctly.

Let me know how it goes!

No, I only have the mat-autocomplete, nothing else, and when I receive results after the keypress I want to filter these hits. Each option in this example have the property price, I only want to show the options that are > to 40.
How do I do that? use this sandbox https://codesandbox.io/s/flamboyant-bash-9xkcr

You shouldn’t filter the results set from the front-end. You should rather use Algolia’s filtering:

With angular-instantsearch v3, you can provide a custom searchFunction to <ais-instantsearch>:
https://www.algolia.com/doc/api-reference/widgets/instantsearch/angular/#widget-param-searchfunction
This searchFunction gives you access to the internal helper, which allows you to add filters for your query:
https://community.algolia.com/algoliasearch-helper-js/reference.html#AlgoliaSearchHelper#addNumericRefinement

In your case something like this should work:

    searchFunction: helper => {
      const page = helper.getPage();
      helper.addNumericRefinement('price', '>', 40);
      helper.setPage(page);
      helper.search();
    }

This works with numbers, but what I actually want to filter is a category, the category comes in a string property. I want to show only the results that meet location_type == “city”, I tried this and it didn’t work:

config = {
indexName: 'MY_NAME',
// disjunctiveFacets: ['location_type'],
searchClient,
searchFunction: helper => {
  helper.facets = ['location_type'];
  const page = helper.getPage();
//helper.parameters = {facets : ['location_type']};
  helper.addFacetRefinement('location_type', 'city');
  // helper.addDisjunctiveFacetRefinement('location_type', 'city');
  helper.setPage(page);
  helper.search();
}

receive this error
ERROR Error: location_type is not defined in the facets attribute of the helper configuration

This sounds like you didn’t declare location_type as a disjunctive facet first.
To do this, you need to add the following searchParameter.

searchParameters = {    disjunctiveFacets: ['location_type']    }

For example:

<ais-configure [searchParameters]="{ hitsPerPage: 5, disjunctiveFacets: ['location_type'] }"></ais-configure>

I only have the ais-instantsearch and Material Autocomplete component in the html

<ais-instantsearch [config]="config">
    <app-autocomplete (onSelectDestination)="selectDestination($event)"></app-autocomplete>
</ais-instantsearch>

Where I define the Search Parameters?
How I define the disjuntiveFacet in the helper?
I want to refine the results of the mat-autocomplete, initial results.

just add <ais-configure [searchParameters]="{ hitsPerPage: 5, disjunctiveFacets: ['location_type'] }"></ais-configure> after app-autocomplete

I tried this

config = {
    indexName: 'prod_locations',
    searchClient,
    searchFunction: helper => {
      if (helper.state.query === "") {
        return;
      }
      const page = helper.getPage();
      helper.addFacetRefinement('location_type', 'city');
      helper.setPage(page);
      helper.search();
    }
  }

<ais-instantsearch [config]="config">
    <app-autocomplete (onSelectDestination)="selectDestination($event)" ></app-autocomplete>
   <ais-configure [searchParameters]="{ hitsPerPage: 5, disjunctiveFacets: ['location_type'] }"></ais-configure>
</ais-instantsearch>

And same error.

please send a codesandbox with minimal code showcasing your error

In this example, How can I only receive results that match “brand:Platinum” (example)