Skip to content

Error: No provider for InjectionToken mat-autocomplete-scroll-strategy  #35759

Closed

Description

@schinks

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</ViewContainerRef.prototype.createComponent@http://localhost:4200/vendor.js:46481:53
./src/app/dynamic-loader/dynamic-loader.service.ts/DynamicLoaderService.prototype.addComponentToContainer/obs<@http://localhost:4200/main.js:583:23
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invoke@http://localhost:4200/polyfills.js:2740:30
onInvoke@http://localhost:4200/vendor.js:63629:33
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invoke@http://localhost:4200/polyfills.js:2739:36
./node_modules/zone.js/dist/zone.js/</Zone$1</Zone</Zone.prototype.run@http://localhost:4200/polyfills.js:2497:47
scheduleResolveOrReject/<@http://localhost:4200/polyfills.js:3238:38
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:2775:35
onInvokeTask@http://localhost:4200/vendor.js:63617:33
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:2774:40
./node_modules/zone.js/dist/zone.js/</Zone$1</Zone</Zone.prototype.runTask@http://localhost:4200/polyfills.js:2542:51
drainMicroTaskQueue@http://localhost:4200/polyfills.js:2955:39

Activity

  1. added this to the needsTriage milestone on Feb 28, 2020
  2. kara commented on Feb 28, 2020

    @kara
    Contributor

    @schinks Can you create a minimal repro on ng-run or Stackblitz? In it's current state, the snippet is too large to be actionable by the team.

  3. added
    area: coreIssues related to the framework runtime
    needs reproductionThis issue needs a reproduction in order for the team to investigate further
    and removed
    area: coreIssues related to the framework runtime
    on Feb 28, 2020
  4. schinks commented on Feb 28, 2020

    @schinks
    Author

    @schinks Can you create a minimal repro on ng-run or Stackblitz? In it's current state, the snippet is too large to be actionable by the team.

    Is it possible to create a stackBlitz using Angular 9 and Material?

  5. schinks commented on Feb 28, 2020

    @schinks
    Author

    I see that ng-run defaults to 9 so I'll give that a try. Thanks.

  6. schinks commented on Mar 2, 2020

    @schinks
    Author

    @kara I am having problems using stackBlitz (can't get ng 9) and ng-run is giving an error after installing material. Can I just create a github repo for you to use?

  7. pkozlowski-opensource commented on Mar 3, 2020

    @pkozlowski-opensource
    Member

    @schinks if you've got troubles using stackblitz, you could try https://ng-run.com/. GitHub repo is more problematic (takes us more time to understand what is going on) but would be OK if you can't reproduce it otherwise.

    In any case please try to keep the reproduce scenario to the absolute minimum...

  8. schinks commented on Mar 3, 2020

    @schinks
    Author

    I got ng-run to work and the error is being thrown there. Run the app and click the search button, the error should be in F12. ng-run project Note the comment in the template file for search component.

  9. added
    regressionIndicates than the issue relates to something that worked in a previous version
    and removed
    needs reproductionThis issue needs a reproduction in order for the team to investigate further
    on Mar 5, 2020
  10. bollerdominik commented on Mar 14, 2020

    @bollerdominik

    I am also having this exact issue when having a lazy loaded module with MatAutocomplete

  11. 21 remaining items

  12. AshMcConnell commented on Oct 7, 2020

    @AshMcConnell

    @JoostK Thanks for your explanation, it helped me a lot. I seem to be having problems getting it to work in production mode. I have included "src/app/**/*.component.ts", in the tsconfig.app.json, but I still get this error when I use ng serve --prod (only to test)

    Error: C:\Dev\bucardo-web\src\app\+enquiries\enquiries.component.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property. at AngularCompilerPlugin.getCompiledFile (C:\Dev\bucardo-web\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:933:23)

    Do you know what I might have done wrong?
    Thanks!

  13. JoostK commented on Oct 7, 2020

    @JoostK
    Member

    @AshMcConnell sorry, that doesn't ring a bell. It might be that src/app/**/*.component.ts is resolved against a base url that starts at src, so you may want to try app/**/*.component.ts? I don't know the logic in the CLI's AngularCompilerPlugin to give you a better hint at the moment.

  14. AshMcConnell commented on Oct 7, 2020

    @AshMcConnell

    Thanks @JoostK I'll give it a go. Odd that it works in non-production mode though

  15. tomasdev commented on Oct 8, 2020

    @tomasdev

    MatTooltipModule also throws ERROR Error: NullInjectorError: No provider for InjectionToken mat-tooltip-scroll-strategy!

    The fix was the same as before, to import MatTooltipModule in the App-level module, and not inside a sub-component. The isolated case in StackBlitz works fine though https://stackblitz.com/edit/angular-nw6rvl

  16. csbenjamin commented on Nov 30, 2020

    @csbenjamin

    @JoostK Thanks for your solution.

    EDIT: Please bear in mind that the example above will create a new instance of SearchModule each time, which may not be desirable. Consider caching the ngModule somewhere (or even just factory in this case) but keep in mind that this instance is specific to a parent Injector, which is this.container.injector in this case.

    As you said, the code given will create a new instance of the module each time. And we can solve this easily creating a cache. I have a module, say FeatureModule, that I would like to use in loadChildren of the Router module. Also I would like to use a lazy loaded FeatureComponent in another module. It turns out that FeatureComponent is declared in FeatureModule and depends on a service that it provides. So, I use your solution to load the FeatureModule and to create the FeatureComponent. But if latter on, I navigate to a url which loads the FeatureModule lazily, then I will have two instances of the FeatureModule, one in my custom cache and another in the Router cache. Is there a way to use the Router cache instead my custom cache to avoid having two instances of the FeatureModule?

  17. barnabasbartha commented on Jul 9, 2021

    @barnabasbartha

    The fix was the same as before, to import MatTooltipModule in the App-level module, and not inside a sub-component.
    Is there a way to avoid importing it into the AppModule but to the lazy loaded modules where needed?

  18. parys commented on Jan 29, 2022

    @parys

    Any news? Issue relates to any module/provider that is was not imported before lazy module. This issue forces me to Import miss modules and Providers to app level, so lazy loading is losing sense because of I have already imported all heavy staff to app level.

  19. devashishSarmah commented on Feb 18, 2022

    @devashishSarmah
    Contributor

    I was struggling with the same issue.
    providing MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER and MAT_SELECT_SCROLL_STRATEGY_PROVIDER in the component level solved it for me.

    providers: [
      MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER,
      MAT_SELECT_SCROLL_STRATEGY_PROVIDER,
    ],
    
  20. jessicajaniuk commented on Apr 27, 2022

    @jessicajaniuk
    Contributor

    This is working as designed, but with a bit of a design flaw. This is mitigated in standalone components, but of course would require the effort to make your app use standalone components. The workaround is to import the ngmodule or to use the ngModuleRef of the module so that it's included in your module dependency graph.

  21. angular-automatic-lock-bot commented on May 28, 2022

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  22. locked and limited conversation to collaborators on May 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions