Federico Navarrete
Federico Navarrete

Reputation: 3274

NullInjectorError: No provider for MatBottomSheet

I'm trying to add a MatBottomSheet to an app that I'm building in Angular 13. I'm trying to follow the example here:

https://material.angular.io/components/bottom-sheet/examples

However, I constantly fail and get this error in the browser:

core.mjs:6495 ERROR NullInjectorError: R3InjectorError(AppModule)[MatBottomSheet -> MatBottomSheet -> MatBottomSheet]: NullInjectorError: No provider for MatBottomSheet! at NullInjector.get (core.mjs:11139) at R3Injector.get (core.mjs:11306) at R3Injector.get (core.mjs:11306) at R3Injector.get (core.mjs:11306) at NgModuleRef.get (core.mjs:22189) at Object.get (core.mjs:21862) at lookupTokenUsingModuleInjector (core.mjs:3349) at getOrCreateInjectable (core.mjs:3461) at Module.ɵɵdirectiveInject (core.mjs:14720) at NodeInjectorFactory.FooterResultComponent_Factory [as factory] (footer-result.component.ts:10)

This is my app.module.ts where I think I have declared the required dependencies:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LeafletModule } from '@asymmetrik/ngx-leaflet';
import { MapComponent } from './home/map/map.component';
import { SearchbarComponent } from './home/searchbar/searchbar.component';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MapResultComponent } from './result/map-result/map-result.component';
import { FooterResultComponent } from './result/footer-result/footer-result.component';
import { MatSidenavModule } from '@angular/material/sidenav';
import { BottomSheetOverviewComponent } from './result/footer-result/bottom-sheet-overview/bottom-sheet-overview.component';
import {MatBottomSheetRef, MAT_BOTTOM_SHEET_DATA} from '@angular/material/bottom-sheet';

@NgModule({
  declarations: [
    AppComponent,
    MapComponent,
    SearchbarComponent,
    MapResultComponent,
    FooterResultComponent,
    BottomSheetOverviewComponent
  ],
  imports: [
    BrowserModule,
    MatListModule,
    AppRoutingModule,
    MatSidenavModule,
    BrowserAnimationsModule,
    LeafletModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    FormsModule,
    MatIconModule,
    ReactiveFormsModule,
    MatAutocompleteModule
  ],
  providers: [
    { provide: MatBottomSheetRef, useValue: {} },
    { provide: MAT_BOTTOM_SHEET_DATA, useValue: {} }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

This is the structure of the section for my app:

preview

The first part is the footer component that triggers the Bottom Sheet:

footer-result.component.ts:

import { Component, OnInit } from '@angular/core';
import { MatBottomSheet } from '@angular/material/bottom-sheet';
import { BottomSheetOverviewComponent } from './bottom-sheet-overview/bottom-sheet-overview.component';

@Component({
  selector: 'app-footer-result',
  templateUrl: './footer-result.component.html',
  styleUrls: ['./footer-result.component.css']
})
export class FooterResultComponent implements OnInit {

  constructor(private _bottomSheet: MatBottomSheet) {}

  openBottomSheet(): void {
    this._bottomSheet.open(BottomSheetOverviewComponent);
  }

  ngOnInit(): void {
  }

}

footer-result.component.html:

<div id="resultFooter">
  <a (click)="openBottomSheet()" id="moreIcon">
    <mat-icon>more_horiz</mat-icon>
  </a>
</div>

This is where I try to implement the Bottom Sheet:

bottom-sheet-overview.component.html:

<mat-nav-list>
  <a href="https://keep.google.com/" mat-list-item (click)="openLink($event)">
    <span mat-line>Google Keep</span>
    <span mat-line>Add to a note</span>
  </a>

  <a href="https://docs.google.com/" mat-list-item (click)="openLink($event)">
    <span mat-line>Google Docs</span>
    <span mat-line>Embed in a document</span>
  </a>

  <a href="https://plus.google.com/" mat-list-item (click)="openLink($event)">
    <span mat-line>Google Plus</span>
    <span mat-line>Share with your friends</span>
  </a>

  <a href="https://hangouts.google.com/" mat-list-item (click)="openLink($event)">
    <span mat-line>Google Hangouts</span>
    <span mat-line>Show to your coworkers</span>
  </a>
</mat-nav-list>

bottom-sheet-overview.component.spec.ts:

import { Component, OnInit } from '@angular/core';
import { MatBottomSheetRef } from '@angular/material/bottom-sheet';

@Component({
  selector: 'app-bottom-sheet-overview',
  templateUrl: './bottom-sheet-overview.component.html',
  styleUrls: ['./bottom-sheet-overview.component.css']
})
export class BottomSheetOverviewComponent implements OnInit {

  constructor(private _bottomSheetRef: MatBottomSheetRef<BottomSheetOverviewComponent>) {}

  ngOnInit(): void {
  }

  openLink(event: MouseEvent): void {
    this._bottomSheetRef.dismiss();
    event.preventDefault();
  }

}

This is my repo if you want to inspect it:

https://github.com/SupernovaIC/holma

Also, you can check the error here:

https://stackblitz.com/edit/angular-ivy-gmayup?file=src/app/app.module.ts

Honestly, I don't know what I'm missing. I was trying to do it all in one typescript file as in the example, but the HTML stopped recognizing the material angular components.

Any idea what am I doing wrong?

Upvotes: 3

Views: 4406

Answers (1)

Diego Bascans
Diego Bascans

Reputation: 1149

You have different references in your module, the MatBottomSheetRef is not a service, change it for MatBottomSheet. I tested it in your code an it's working.

Also you have to add BrowserAnimationsModule in order to work.

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

    @NgModule({
  imports: [
    BrowserAnimationsModule 
    BrowserModule,
    FormsModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatSidenavModule,
    MatListModule,
    MatIconModule,
    MatAutocompleteModule,
  ],
  declarations: [
    AppComponent,
    HelloComponent,
    FooterResultComponent,
    BottomSheetOverviewComponent,
  ],
  bootstrap: [AppComponent],
  providers: [
    { provide: MatBottomSheet },
    { provide: MAT_BOTTOM_SHEET_DATA, useValue: {} },
  ],
})
export class AppModule {}

enter image description here

Upvotes: 4

Related Questions