4

When I pass custom data via the optional config object in material bottom sheet [open][1] method, my component data - if loaded asynchronously, is not available / doesn't render. If I hardcode the component data or don't pass a config object to the open function, the component data loads.

teams.component.ts - contains bottom sheet open method

export class TeamsComponent implements OnInit {
  teams: Team[];
  constructor(
    private teamService: TeamService,
    private messageService: MessageService,
    private bottomSheet: MatBottomSheet
  ) { }

    showActiveDivisionsInBottomSheet() {
        const ref = this.bottomSheet.open(ActiveDivisionsComponent, {
          data: { heading: 'Switch to new division' },
        });
    }
}

teams.component.html

<ul>
  <li *ngFor="let team of teams">
    {{ team.name }}
    <button (click)="showActiveDivisionsInBottomSheet()" mat-raised-button>{{ team.division.name }}</button>
  </li>
</ul>

active-divisions.component.ts - the component passed to the material bottom sheet

export class ActiveDivisionsComponent implements OnInit {
  divisions: Division[];
  constructor(
    @Inject(MAT_BOTTOM_SHEET_DATA) public data: any,
    private divisionsService: DivisionsService
  ) { }
  ngOnInit() {
    this.getDivisions();
  }
  getDivisions(): void {
    this.divisionsService.getDivisions()
      .subscribe(response => this.divisions = response['data']);
  }
}

active-divisions.component.html

<h1>{{ data.heading }}</h1>
<ul>
  <li *ngFor="let division of divisions">
    {{ division.name }}
  </li>
</ul>

Here, only the heading passed in through the config parameter of the bottom sheet open() method is rendered. Remove this config option and the divisions are loaded.

However - hardcode the divisions array in active-divisions.component rather than fetch it from the service:

divisions: Division[] = [
    {id: 1, name: 'Pool A'},
    {id: 2, name: 'Pool B'}
  ];

And both the data passed to the bottom sheet component, and the divisions array now render.

For this example I could obviously put the heading within the active-divisions component, but in reality I'll be passing the current division of the selected team, so that it can pre populate the bottom sheet.

1 Answer 1

8

You need to trigger change-detection to update the sheet:

import { Component, OnInit, Inject, ChangeDetectorRef } from '@angular/core';

constructor(private changeDetectorRef: ChangeDetectorRef) { }

ngOnInit() {
    this.yourService.getData().subscribe(data => {
        // do your stuff and notify of changes like this
        this.changeDetectorRef.detectChanges();
    });
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.