Angular 9 lazy load component error: No provider for InjectionToken mat-autocomplete-scroll-strategy
Asked Answered
B

5

5

I upgraded my project from Angular 8 to 9 and refactored my code to take advantage of the ability to lazy load components. For most of my components this works great, but I have one that is throwing an error and I need help resolving the issue.

Here is my component code followed by the error. The module is defined in the same file as the component.


    import { Component, OnInit, OnDestroy, NgModule } from '@angular/core';
    import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { switchMap, debounceTime, tap, filter } from 'rxjs/operators';
    import { MatFormFieldModule, MatInputModule, MatAutocompleteModule, MatButtonModule, MatProgressSpinnerModule, MatIconModule, MatDialogModule } from '@angular/material';

    import { SearchService } from './search.service';
    import { SuggestResult } from './suggest-result';
    import { CommonModule } from '@angular/common';
    import { HttpClientModule } from '@angular/common/http';
    import { SharedModule } from 'src/app/shared/shared.module';

    @Component({
        selector: 'app-search',
        templateUrl: './search.component.html',
        styleUrls: ['./search.component.scss'],
        providers: [ FormBuilder]
    })
    export class SearchComponent implements OnInit, OnDestroy {

    //code removed

    }

    @NgModule({
        imports: [
            CommonModule,
            HttpClientModule,
            FormsModule,
            ReactiveFormsModule,
            MatFormFieldModule,
            MatInputModule,
            MatAutocompleteModule,
            MatButtonModule,
            MatProgressSpinnerModule,
            MatIconModule,
            SharedModule,
            MatDialogModule
        ],
        declarations: [SearchComponent]
    })
    export class SearchModule { }
    <div>
        <div class="form-container">
            <form [formGroup]='resultsForm'>
                <mat-form-field [class.mat-form-field-invalid]="!formFieldValid">
                    <input matInput placeholder="Search term" type="search" [matAutocomplete]="SearchAuto" formControlName='SearchUserInput'>
                </mat-form-field>

                <div *ngIf="!formFieldValid" class="error-msg"> {{ errorMessage }} </div>

                <mat-autocomplete #SearchAuto="matAutocomplete" [displayWith]="getSelectedText"
                    (optionSelected)='onItemSelected($event.option.value)'>
                    <mat-option *ngIf="isLoading" class="is-loading">
                        <mat-spinner mode="indeterminate" diameter="25"></mat-spinner>
                    </mat-option>

                    <ng-container *ngIf="!isLoading">
                        <mat-option *ngFor="let result of filteredResults" [value]="result">
                            <span>{{ result.name }}</span>
                        </mat-option>
                    </ng-container>
                </mat-autocomplete>
           </form>
            <mat-icon>search</mat-icon>
            <button mat-button *ngIf="isNotEmpty()" matSuffix mat-icon-button aria-label="Clear" (click)="clearSearch()">
                <mat-icon>close</mat-icon>
            </button>
        </div>
    </div>

The error:

null: Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[InjectionToken mat-autocomplete-scroll-strategy -> InjectionToken mat-autocomplete-scroll-strategy -> InjectionToken mat-autocomplete-scroll-strategy]: NullInjectorError: No provider for InjectionToken mat-autocomplete-scroll-strategy! ./node_modules/@angular/core/ivy_ngcc/fesm5/core.js/NullInjector.prototype.get@http//localhost:4200/vendor.js:37066:25" ./node_modules/@angular/core/ivy_ngcc/fesm5/core.js/R3Injector.prototype.get@http//localhost:4200/vendor.js:47422:33 ./node_modules/@angular/core/ivy_ngcc/fesm5/core.js/R3Injector.prototype.get@http//localhost:4200/vendor.js:47422:33 ./node_modules/@angular/core/ivy_ngcc/fesm5/core.js/R3Injector.prototype.get@http//localhost:4200/vendor.js:47422:33 ./node_modules/@angular/core/ivy_ngcc/fesm5/core.js/NgModuleRef$1.prototype.get@http//localhost:4200/vendor.js:60382:33 get@http//localhost:4200/vendor.js:58703:35 getOrCreateInjectable@http//localhost:4200/vendor.js:39763:39 ɵɵdirectiveInject@http//localhost:4200/vendor.js:50290:12 MatAutocompleteTrigger_Factory@http//localhost:4200/vendor.js:76965:788 getNodeInjectable@http//localhost:4200/vendor.js:39871:44 searchTokensOnInjector@http//localhost:4200/vendor.js:39807:16 getOrCreateInjectable@http//localhost:4200/vendor.js:39729:58 ɵɵdirectiveInject@http//localhost:4200/vendor.js:50290:12 ɵɵinject@http//localhost:4200/vendor.js:36956:57 factory@http//localhost:4200/vendor.js:47681:44 multiResolve@http//localhost:4200/vendor.js:55407:21 multiProvidersFactoryResolver@http//localhost:4200/vendor.js:55372:12 getNodeInjectable@http//localhost:4200/vendor.js:39871:44 searchTokensOnInjector@http//localhost:4200/vendor.js:39807:16 getOrCreateInjectable@http//localhost:4200/vendor.js:39729:58 ɵɵdirectiveInject@http//localhost:4200/vendor.js:50290:12 FormControlName_Factory@http//localhost:4200/vendor.js:74579:400 getNodeInjectable@http//localhost:4200/vendor.js:39871:44 searchTokensOnInjector@http//localhost:4200/vendor.js:39807:16 getOrCreateInjectable@http//localhost:4200/vendor.js:39729:58 ɵɵdirectiveInject@http//localhost:4200/vendor.js:50290:12 ɵɵinject@http//localhost:4200/vendor.js:36956:57 factory@http//localhost:4200/vendor.js:47681:44 getNodeInjectable@http//localhost:4200/vendor.js:39871:44 searchTokensOnInjector@http//localhost:4200/vendor.js:39807:16 getOrCreateInjectable@http//localhost:4200/vendor.js:39729:58 ɵɵdirectiveInject@http//localhost:4200/vendor.js:50290:12 MatInput_Factory@http//localhost:4200/vendor.js:99837:370 getNodeInjectable@http//localhost:4200/vendor.js:39871:44 instantiateAllDirectives@http//localhost:4200/vendor.js:44362:42 createDirectivesInstances@http//localhost:4200/vendor.js:43753:29 ɵɵelementStart@http//localhost:4200/vendor.js:50436:34 ɵɵelement@http//localhost:4200/vendor.js:50487:19 SearchComponent_Template@http//localhost:4200/search-search-search-component.js:190:56 executeTemplate@http//localhost:4200/vendor.js:43726:19 renderView@http//localhost:4200/vendor.js:43551:28 renderComponent@http//localhost:4200/vendor.js:44741:15 renderChildComponents@http//localhost:4200/vendor.js:43412:24 renderView@http//localhost:4200/vendor.js:43576:34 ./node_modules/@angular/core/ivy_ngcc/fesm5/core.js/ComponentFactory.prototype.create@http//localhost:4200/vendor.js:58804:23 createContainerRef/R3ViewContainerRef

Blab answered 28/2, 2020 at 18:46 Comment(1)
may be mat-autocomplete-scroll-strategy have service which are not injectedCorrespond
G
5

Inject the defaults into your app.module.ts

  providers: [
    MAT_AUTOCOMPLETE_SCROLL_STRATEGY
  ],


For us it was matPaginator's tool tips causing a similar error which was resolved with

  providers: [
    MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER,
    MAT_SELECT_SCROLL_STRATEGY_PROVIDER
  ],
Gildagildas answered 19/4, 2020 at 5:51 Comment(1)
I don't recall for sure, but I think I tried your suggestion and it did not work. In the end the solution was this github.com/angular/angular/issues/35759#issuecomment-601444856Blab
A
1

In my case i try to implement Chips Autocomplete from here

https://material.angular.io/components/chips/examples

Ended up with error that there is No provider for InjectionToken mat-autocomplete-scroll-strategy.

Fixed with added this to my SharedModule (in your case maybe it will be in AppModule)

import {ScrollingModule} from '@angular/cdk/scrolling';
Ackler answered 25/2, 2021 at 8:58 Comment(0)
I
1

Added A Provider on Component Level

providers: [
 {
  provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
  useValue: MAT_SELECT_SCROLL_STRATEGY_PROVIDER,
 },
],

This resolved the issue for me

Indomitable answered 29/10, 2021 at 10:34 Comment(0)
C
0

You need to import ReactiveFormsModule from @angular/forms into your NgModule, otherwise you will get the "NullInjectorError: No provider for InjectionToken mat-autocomplete-scroll-strategy!" error.

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
    declarations: [
    ],
    imports: [
        // ...
        ReactiveFormsModule, // <--
    ],
    providers: [
    ]
})

See https://material.angular.io/components/autocomplete/overview#simple-autocomplete

Camphorate answered 10/5, 2021 at 9:16 Comment(0)
D
0

I had to import the MatAutoCompleteModule to the root module app.module.ts, even though other angular material imports worked in a sub module (**/*.module.ts) without needing the import in the root module as well.

In additional, I was unable to use MAT_AUTOCOMPLETE_SCROLL_STRATEGY as a provider in Angular 14.

Dorren answered 30/9, 2023 at 18:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.