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

NullInjectorError: No provider for NgAisInstantSearch! #948

Closed Karman40 closed 2 years ago

Karman40 commented 2 years ago

Hello,

I wanted to make an application where there is a central table to which only the template and variables need to be passed, but unfortunately I got stuck during the algola setup. Everything works without the custom widget. But when I put the component in the search engine, I get the following error:

Error message:

ERROR NullInjectorError: R3InjectorError(ServersAllModule)[NgAisInstantSearch -> NgAisInstantSearch -> NgAisInstantSearch -> NgAisInstantSearch -> NgAisInstantSearch -> NgAisInstantSearch]: 
  NullInjectorError: No provider for NgAisInstantSearch!

list.component

      <app-table [AisConfig]="AisConfig" [TableConfig]="TableConfig">
        <app-servers-all-filter headerDataFilter></app-servers-all-filter>

        <thead tableHead>
          <th tableHeadItem style="width: 75px;">NO</th>
          ....
        </thead>

        <tbody tableBody>
          <ng-template let-hits="hits" let-results="results">
            <tr *ngFor="let server of hits; trackBy:trackById let i = index" tableBodyRow>
              <td>{{ server.seq }}</td>
              ....
            </tr>
          </ng-template>
        </tbody>
      </app-table>

app-table

<ais-instantsearch [config]="AisConfig">

  <div class="table-box">
    <div *ngIf="TableConfig?.header" class="title-small">
      <h2 *ngIf="TableConfig.header?.title as title" class="title-bold">{{ title }}</h2>
      <p *ngIf="TableConfig.header?.description as description" class="title-text">{{ description }}</p>
      <ng-content select="[headerDataFilter]"></ng-content>     <-- I want to dynamically load the search engine, filters here ...
    </div>

    <ais-hits>
      <ng-template let-hits="hits" let-results="results">
        <table class="table">

          <ng-container [ngTemplateOutlet]="templ" [ngTemplateOutletContext]="{hits: hits, results: results}"></ng-container>
          <ng-content></ng-content>

        </table>
      </ng-template>
    </ais-hits>
  </div>

</ais-instantsearch>

app-servers-all-filter

<app-ais-search-box></app-ais-search-box>

app-ais-search-box

export class AisSearchBoxComponent extends TypedBaseWidget<SearchBoxWidgetDescription, SearchBoxConnectorParams> implements OnInit {

  public state: SearchBoxWidgetDescription['renderState']; // Rendering options
  // {
  //   query: string;
  //   refine: Function;
  //   clear: Function;
  //   isSearchStalled: boolean;
  //   widgetParams: object;
  // }

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

  ngOnInit() {
    this.createWidget(connectSearchBox, {
    //   instance options
    });
    super.ngOnInit();
  }

}

Thank you in advance for your help.

Haroenv commented 2 years ago

Can you reproduce this in a codesandbox? As you didn't mention where in the app you are rendering the search box, is it possible it's outside of the ais-instantsearch component? Every widget needs to be rendered inside InstantSearch for keeping track of the state

Karman40 commented 2 years ago

I'm trying to do a demo The structure is as follows:

shared /

ListComponent

Haroenv commented 2 years ago

in that case TableComponent needs to be the parent of the search component

Karman40 commented 2 years ago

Demo code: https://github.com/Karman40/algolia-widget-error-sample

If you want to receive the error message, enable line 2 of app.component.html. I did a demo algolia project with index.

Haroenv commented 2 years ago

This is a limitation of angular @Karman40, an injector needs to be in the outer component where the children are used, "children" don't get automatic access.

Here's a PR to your example with those changes which works for me: https://github.com/Karman40/algolia-widget-error-sample/pull/1

I'll close this issue for now, hope you have a great time implementing further!

Karman40 commented 2 years ago

Thanks for the help! I'm sorry to hear that the original solution doesn't work.

Haroenv commented 2 years ago

Have you seen the pull request I made to your example @Karman40 ?

sonicparke commented 1 year ago

Man it would be nice if that repo was still active so I could figure out what I'm doing wrong. I'm getting the same error.