NullInjectorError: No provider for NgAisInstantSearch!
Karman40 opened this issue · 8 comments
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.
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
I'm trying to do a demo
The structure is as follows:
shared /
- TableComponent - Here is ais-instantsearch, ng-content handles incoming code.
ListComponent
- import TableComponent
- import SearComponent
- import more algolia widget
in that case TableComponent needs to be the parent of the search component
Demo code: https://github.com/Karman40/algolia-widget-error-sample
- npm i
- ng s
If you want to receive the error message, enable line 2 of app.component.html.
I did a demo algolia project with index.
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!
Thanks for the help! I'm sorry to hear that the original solution doesn't work.
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.