Angular InstantSearch Autocomplete Problems

Hi Guys,

Trying to implement the following Autocomplete UX patterns.

I’m however getting a range of Typescript problems with this approach, mainly in the autocomplete.component.ts file in the example code sandbox.

First of all ngOnInit doesn’t seem to have been implemented properly.

Secondly Typescript is warning me that several required members of BaseWidget haven’t been implemented in this extension component. (app-autocomplete).

These are:

  instantSearchInstance: NgAisInstantSearch;
  parentIndex: NgAisIndex;

And lastly, in F12 console I’m getting the following error on load of the widget.

Cannot read properties of undefined (reading 'addWidgets')

I get the feeling the current documentation on Autocomplete doesn’t match the current version of InstantSearch?

Can someone clear this up?

Thanks,
Rob

After reading your customisation documents and upgrade documents (even though im not upgrading im going straight in at v4). I’ve noticed you have changed from BaseWidget to TypedBaseWIdget.

As a result, best guessing, i’ve updated my code to be the following:

autocomplet.html

<div>
  <input matInput [matAutocomplete]="auto" (keyup)="handleChange($event)" style="width: 100%; padding: 10px"/>
  <mat-autocomplete  #auto="matAutocomplete" style="margin-top: 30px; max-height: 600px">
    <mat-optgroup *ngFor="let index of (state.indices || [])" [label]="index.index">
      <mat-option *ngFor="let options of index.hits" [value]="options.name">
        <div>
          {{options.name}}
        </div>
      </mat-option>
    </mat-optgroup>
  </mat-autocomplete>
</div>

autocomplete.ts

import {Component, forwardRef, Inject, OnInit, Output, EventEmitter } from '@angular/core';
import {BaseWidget, NgAisIndex, NgAisInstantSearch, TypedBaseWidget} from 'angular-instantsearch';
import { connectAutocomplete } from 'instantsearch.js/es/connectors';
import {AutocompleteConnectorParams, AutocompleteWidgetDescription} from 'instantsearch.js/es/connectors/autocomplete/connectAutocomplete';


@Component({
  selector: 'app-search-auto-complete',
  templateUrl: './search-auto-complete.component.html',
  styleUrls: ['./search-auto-complete.component.scss']
})

// @ts-ignore
export class SearchAutoCompleteComponent extends TypedBaseWidget<AutocompleteWidgetDescription, AutocompleteConnectorParams>{

  constructor(
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchParent,
  ) {
    super('SearchAutoCompleteComponent');
  }

  parentIndex?: NgAisIndex;
  public state: AutocompleteWidgetDescription['renderState'];

  public handleChange($event: KeyboardEvent) {
    this.state.refine(($event.target as HTMLInputElement).value);
  }

  // tslint:disable-next-line:use-lifecycle-interface
  public ngOnInit() {
    this.createWidget(connectAutocomplete, {});
    super.ngOnInit();
  }

}

That still hasn’t resolved the OnInit issue and 2 unimplemented members issues.

Also, when running in the browser on F12 I now get the following:

ERROR TypeError: Cannot read properties of undefined (reading 'indices')

Please can someone provide a working example on V4 with Angular 11 or recommend that I downgrade to V3.

From reading another thread on this I can see something was missed out in the change log but has since been added and more changes have now been made to my code.

import {Component, forwardRef, Inject, OnInit, Output, EventEmitter, Optional} from '@angular/core';
import {NgAisIndex, NgAisInstantSearch, TypedBaseWidget} from 'angular-instantsearch';
import { connectAutocomplete } from 'instantsearch.js/es/connectors';
import type {AutocompleteConnectorParams, AutocompleteWidgetDescription} from 'instantsearch.js/es/connectors/autocomplete/connectAutocomplete';

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'search-auto-complete',
  templateUrl: './search-auto-complete.component.html',
  styleUrls: ['./search-auto-complete.component.scss']
})

// tslint:disable-next-line:max-line-length
export class SearchAutoCompleteComponent extends TypedBaseWidget<AutocompleteWidgetDescription, AutocompleteConnectorParams> implements OnInit{


  constructor(
    @Inject(forwardRef(() => NgAisIndex))
    @Optional()
    public parentIndex: NgAisIndex,
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchInstance: NgAisInstantSearch
  ) {
    super('SearchAutoCompleteComponent');
  }

  public state: AutocompleteWidgetDescription['renderState'];

  public handleChange($event: KeyboardEvent) {
    this.state.refine(($event.target as HTMLInputElement).value);
  }

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


}

The addition was the extra constructor parameters, this has taken care of some of the errors but i’m still getting the state as being undefined.

Can someone please help me and tell me where I’ve gone wrong here as there is currently no live example for V4 InstantSearch for AutoComplete.

I appreciaite it takes time to make these new examples, but you have chosen to release a new version of your software, people have upgraded and have no source of truth on the changes needed to make other than an incomplete changelog.

At the very least I ask that someone can come simply back to me and just advise if there is an issue with V4 InstantSearch or an issue with my code.

Thanks,
Rob

After further guesswork, I can confirm the below solution worked for getting it to work on V4.

 constructor(
    @Inject(forwardRef(() => NgAisIndex))
    @Optional()
    public parentIndex: NgAisIndex,
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchInstance: NgAisInstantSearch
  ) {
    super('SearchAutoCompleteComponent');
  }

But you must also remember to add *ngIf=“state” to the parent div as the state isn’t immediately available.

The only issue which remains and I cannot find any documentaiton, knowledge or discussion about is Multi index autocomplete.

When trying to add another index using the code provided in the example:

        this.createWidget(connectAutocomplete, {
            indices: [
                { value: "actors" } // adds index `actors` to search
            ]
        });

I encounter the following error:

TS2345: Argument of type '{ indices: { value: string; }[]; }' is not assignable to parameter of type 'AutocompleteConnectorParams'.   Object literal may only specify known properties, and 'indices' does not exist in type 'AutocompleteConnectorParams'.

I managed to resolve this by adding in the ais-index component as per yoru documentation.

Thanks,
Rob

1 Like