The Angular tag <mat-expansion-panel-header> fails to load

Every time I incorporate the mat-expansion-panel-header tag in my HTML, an error pops up in the console.

Referencing the basic expansion panel example from here.

ERROR TypeError: Cannot read property 'pipe' of undefined
at new MatExpansionPanelHeader (expansion.es5.js:326)
at createClass (core.js:9103)
at createDirectiveInstance (core.js:8978)
at createViewNodes (core.js:10198)
at callViewAction (core.js:10514)
at execComponentViewsAction (core.js:10433)
at createViewNodes (core.js:10226)
at createRootView (core.js:10112)
at callWithDebugContext (core.js:11143)
at Object.debugCreateRootView [as createRootView] (core.js:10630)
View_TrainingOptionsComponent_0 @ TrainingOptionsComponent.html:25

I have included MatExpansionModule in module.ts.

Versions mentioned in package.json:

  • "@angular/material": "^6.3.3",
  • "@angular/material-moment-adapter": "^6.3.3",
  • "typescript": "^2.7.2"

<div fxLayoutAlign="space-between stretch" class="options-list-container">
          <div class="options-list">
            <mat-divider class="mat-divider"></mat-divider>
            <mat-accordion *ngFor="let option of filteredHeaders" class="option mat-accordion" data-id="{{option.id}}">
              <mat-expansion-panel #optionPanel>
                <mat-expansion-panel-header class="mat-expansion-panel-header">
                  <mat-panel-title fxFlex.lg="70" fxFlex.xs="70" fxFlex.md="70">
                    {{option.title}}
                  </mat-panel-title>
                  <mat-panel-title fxFlex.lg="15" fxFlex.xs="70" fxFlex.md="70">
                    {{option.dateFrom | date:'dd-MM-yyyy'}}
                  </mat-panel-title>
                  <mat-panel-title class="status" fxFlex.lg="15" fxFlex.xs="15">
                    {{option.price}} + ~{{option.additionalPrice}} EUR
                  </mat-panel-title>
                </mat-expansion-panel-header>
                <app-option-details *ngIf="optionPanel._getExpandedState() === 'expanded'"
                                    [id]="option.id"
                                    (dateEmitter)="getDates($event)">

                </app-option-details>
                <div fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
                  <div fxFlex="50" fxLayout.lt-lg="100" fxLayoutAlign="start center">
                    <button mat-raised-button color="primary" (click)="openEditOption(option.id); editMode = true">EDIT OPTION</button>
                  </div>
                  <div fxFlex="100" fxLayout.lt-lg="100" fxLayoutAlign="end center">
                    <button mat-raised-button color="primary" (click)="openDialog(option);">APPLY</button>
                  </div>
                </div>
              </mat-expansion-panel>
            </mat-accordion>
          </div>
        </div>

component.ts

import { Component, OnInit } from '@angular/core';
import { trigger, style, animate, transition } from '@angular/animations'
import { HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { MatDialog } from '@angular/material';
import { ITrainingOption } from '../shared/trainingOption.model';
import { ISelector } from '../shared/selector.model';
import { IOptionHeader } from '../shared/optionHeader.model';
import { ApiService } from '../shared/api.service';
import { FormGroup, FormControl } from '@angular/forms';
import { ApplicationsComponent } from './applications/applications.component';
import { MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';

export const dateFormat = {
  parse: {
    dateInput: 'l',
  },
  display: {
    dateInput: 'l',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'l',
    monthYearA11yLabel: 'MMMM YYYY',
  },
};

export interface IIsInternalSelect {
  value: boolean;
  viewValue: string;
}

@Component({
  selector: 'app-options',
  templateUrl: './training-options.component.html',
  styleUrls: ['./training-options.component.scss'],
  providers: [
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS, MAT_DATE_FORMATS]
    },
    {
      provide: MAT_DATE_FORMATS,
      useValue: dateFormat
    },
    { provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
    { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
  ],
  animations: [
    trigger(
      'enterAnimation', [
        transition(':enter',
          [
            style({ transform: 'translateX(100%)' }),
            animate('400ms', style({ transform: 'translateX(0)' }))
          ]),
        transition(':leave', [
          style({ transform: 'translateX(0)' }),
          animate('200ms', style({ transform: 'translateX(100%)' }))
        ])
      ]
    )
  ],
})

export class TrainingOptionsComponent implements OnInit {
  constructor(private apiService: ApiService, public dialog: MatDialog) { }

  ngOnInit(): void {
    this.getCategories();
    this.getEventTypes();
    this.getHeaders();
  }

  form = new FormGroup({
    id: new FormControl(),
    title: new FormControl(),
    link: new FormControl(),
    description: new FormControl(),
    categoryId: new FormControl(),
    periodFrom: new FormControl(),
    periodTo: new FormControl(),
    price: new FormControl(),
    additionalPrice: new FormControl(),
    eventTypeId: new FormControl(),
    isInternal: new FormControl(),
    isFullDay: new FormControl(),
    createdById: new FormControl()
  });

  isAddOptionShown: boolean;
  minDateFrom: Date = new Date();
  minDate: Date;
  maxDate: Date;

  categories: ISelector[] = [];
  eventTypes: ISelector[] = [];
  headers: IOptionHeader[] = [];
  filteredHeaders: IOptionHeader[] = [];
  optionDates: Date[] = [];

  organizerTypes: IIsInternalSelect[] = [
    { value: true, viewValue: 'Internal' },
    { value: false, viewValue: 'External' }
  ];

  openDialog(option: IOptionHeader): void {
    this.dialog.open(ApplicationsComponent, {
      data: {
        opt: option,
        dates: this.optionDates
      }
    });
  }

  set searchString(value: string) {
    this.filteredHeaders = value ? this.performFilter(value) : this.headers;
  }

  performFilter(filterBy: string): IOptionHeader[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.headers.filter((header: IOptionHeader) =>
      header.title.toLocaleLowerCase().indexOf(filterBy) !== -1);
  }

  submitOption(option: ITrainingOption) {
    this.apiService.addOrUpdateOption(option).subscribe(() => {
      this.isAddOptionShown = false;
      this.getHeaders();
    });
  }

  getHeaders() {
    this.apiService.getTrainingOptionHeaders().subscribe(
      x => {
        this.headers = x;
        this.filteredHeaders = x;
      }
    );
  }

  getCategories() {
    this.apiService.getCategories().subscribe(
      categories => {
        this.categories = categories;
      });
  }

  getEventTypes() {
    this.apiService.getEventTypes().subscribe(
      eventTypes => {
        this.eventTypes = eventTypes;
      });
  }

  openEditOption(editOptionId: number) {
    this.apiService.getTrainingOption(editOptionId).subscribe(x => {
      this.form.setValue({
        'id': x.id,
        'title': x.title,
        'description': x.description,
        'link': x.link,
        'categoryId': x.categoryId,
        'eventTypeId': x.eventTypeId,
        'isInternal': x.isInternal,
        'price': x.price,
        'additionalPrice': x.additionalPrice,
        'periodFrom': x.periodFrom,
        'periodTo': x.periodTo,
        'isFullDay': x.isFullDay,
        'createdById': x.createdById
      });
      this.isAddOptionShown = true;
      this.minDateFrom = x.periodFrom;
      this.minDate = x.periodFrom;
      this.maxDate = x.periodTo;
    });
  }

  getDates(dates: Date[]) {
    this.optionDates = dates;
  }

  resetForm() {
    this.form.setValue({
      'id': 0,
      'title': '',
      'description': '',
      'link': '',
      'categoryId': '',
      'eventTypeId': '',
      'isInternal': false,
      'price': 0,
      'additionalPrice': 0,
      'periodFrom': null,
      'periodTo': null,
      'isFullDay': false,
      'createdById': '.'
    });
    this.minDateFrom = new Date();
    this.minDate = this.minDateFrom;
    this.maxDate = null;
  }
}

module.ts

import {
  MatExpansionModule,
  MatButtonModule,
  MatButtonToggleModule,
  MatInputModule,
  MatToolbarModule,
  MatIconModule,
  MatListModule,
  MatSelectModule,
  MatDatepickerModule,
  MatNativeDateModule,
} from '@angular/material';
import { MatChipsModule } from '@angular/material/chips';
import { CoreModule } from '../core/core.module';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TrainingOptionsComponent } from './training-options.component';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatCardModule } from '@angular/material/card';
import { CommonModule } from '@angular/common';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ApplicationsComponent } from './applications/applications.component';
import { TrainingRequestsModule } from '../training-requests/training-requests.module';

export const appRoutes: Routes = [
  { path: '', component: TrainingOptionsComponent },
  { path: 'application', component: ApplicationsComponent }
];

@NgModule({
  imports: [
    MatCardModule,
    FlexLayoutModule,
    MatButtonModule,
    MatButtonToggleModule,
    MatInputModule,
    MatToolbarModule,
    MatIconModule,
    MatCheckboxModule,
    MatListModule,
    MatChipsModule,
    MatSelectModule,
    MatDatepickerModule,
    MatNativeDateModule,
    MatExpansionModule,
    CoreModule,
    CommonModule,
    RouterModule.forChild(appRoutes),
    FormsModule,
    ReactiveFormsModule,
    TrainingRequestsModule
  ],
  declarations: [TrainingOptionsComponent, ApplicationsComponent],
  exports: [],
})
export class TrainingOptionsModule { }

UPDATE: Including code snippets. It seems that even after modifying the HTML to match the standard expansion panel example, the issue persists. Link provided above for reference.

Answer №1

The likely reason is a discrepancy in versions between @angular/material and @angular/cdk.

It is crucial that they match perfectly.

Reference: Comment on GitHub issue

Answer №2

Sharing your HTML structure and TypeScript code for that component could provide valuable insight.

In a simple case, importing and exporting the MatExpansionModule on your module.ts file is essential, followed by using the appropriate HTML tag <mat-expansion-panel>.

It appears that you are attempting to use a Pipe on undefined information. Sharing your current HTML layout would be beneficial in resolving this issue.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for displaying detailed information about a single product on an Ecommerce page

Currently in the process of developing my Ecommerce project, I have successfully created a product grid with links to each specific product. However, I am facing an issue where I am unable to view the data of each individual item. Below is the code for my ...

Exporting a Middleware member is essential for defining Koa middleware type definitions

Currently utilizing KoA with Typescript and incorporating the KoA middleware KoA-static and KoA-bodyparser. Ensuring that I have installed the type definition packages @types/koa, @types/koa-bodyparser, and @types/koa-static. However, upon running tsc, enc ...

Imitate dependencies using Mocha and Typescript

In my typescript project, I am using mocha. Let's consider two modules: // http.ts export class Http { } // app.ts import Http from './http'; export class App { } I want to know how to mock the Http module while testing the App. The te ...

Angular 2 encountered an issue trying to identify the module for the ManagersService class

Encountering an issue when attempting to build using ng build -prod. The error message is as follows: ERROR in Cannot determine the module for class ManagersService in C:/Test/src/app/shared/common/managers/managers.service.ts! Add ManagersService to the ...

What is the best way to delay an observable from triggering the next event?

In my Angular project, I am implementing RxJs with two subjects. s1.next() s1.subscribe(() => { // perform some operation and then trigger the event for s2 s2.next() }); s2.subscribe(() => { // perform some operat ...

Bringing in Static Functions Typescript

Having trouble importing a static class function into my main.js file and encountering an error after compiling with tsc: TypeError: Cannot read property 'router' of undefined at Object. (path/to/main.js:36:27)> Various attempts to assign a ...

Unable to apply "@angular/fire" using ng add command because the package does not have schematic support

Just completed the upgrade to Angular CLI 12.0.0, alongside Node 14.17.0 and npm 7.13.0 Encountering an issue when attempting to integrate Angular Fire into my project: ng add @angular/fire The following message pops up: The package @angular/[email ...

Accessing and sending only the body part of an HTTP response in Angular 7 test cases: A comprehensive guide

Currently, I am working on creating unit test cases in Angular 7 for a Component that utilizes an asynchronous service. This is the content of my component file: submitLoginForm() { if (this.loginForm.valid) { // send a http request to save t ...

Ways to "Compile out" log commands

In my typescript project, there is a section of code dedicated to creating debug information. However, upon profiling the application, I discovered that this debug code is causing a significant performance impact. Currently, my approach involves setting a ...

The type 'MouseEvent<HTMLButtonElement, MouseEvent>' cannot be matched with the type 'boolean'

Just starting out with TS and running into a problem that TS is pointing out to me. Error: Type '(x: boolean) => void' is not compatible with type '(e: MouseEvent<HTMLButtonElement, MouseEvent>) => void'. Parameters ' ...

Is it possible to utilize an await in an rxjs observable?

Implementing an interceptor for my HTTP requests requires the use of the access token from the user instance. Within my app component, I initialize the user: app.component.ts private async restoreUser(): Promise<UserModel | any> { // ... some vi ...

Apply a CSS class when the tab key is pressed by the user

Currently in my Angular 14 project, I am working on a feature where I need to apply "display: block" to an element once the user reaches it using the tab key. However, I am struggling with removing the "display: block" when the user tabs out of the element ...

Using Observable.subscribe in Angular 8 empties my user class

Just starting out with Angular and I have a question about making API calls. GetUserDetailsfromID(id:number):Observable<UserResponse> { let token = localStorage.getItem("userToken"); return this.http.get<UserResponse>(this.base ...

Problem with Packaging Angular and Spring Boot Applications

My current project structure consists of a spring boot angular project +--app-ui |--+--src |--+--dist |--app-backend |--+--src |--+--+--main |--+--+--+--resources |--+--+--+--+--static |--+--+--+--java The app-ui directory contains the Angular 6 code, wh ...

Encountering a situation where the data retrieved from Firestore in Angular TypeScript is returning as

I am encountering an issue with retrieving the eventID value from my Events collection in Firestore. Although I am able to successfully display all the events in my app, I require the eventID for additional functionalities. As someone new to TypeScript an ...

Blur function not performing as anticipated

I am attempting to achieve a blur effect on a dialog pop-up. Currently, I am using the primeng p-dialog component for this purpose. <p-panelMenu [model]="items" [style]="{'width':'300px'}"></p-panelMenu> <p-dialog head ...

Automatically convert TypeScript packages from another workspace in Turborepo with transpilation

I have set up a Turborepo-based monorepo with my primary TypeScript application named @myscope/tsapp. This application utilizes another TypeScript package within the same repository called @myscope/tspackage. For reference, you can view the example reposit ...

Enhance your Angular experience by adding two new columns to your JSONArray table

I am faced with a JSON-Array dilemma. Array(8) 0: (3) ["Test", "1", "222"] 1: (3) ["Test", "2", "333"] 2: (3) ["Test", "3", "444"] 3: (3) ["Test", "4", "555"] 4: (3) ["Test", "5", "666"] 5: (3) ["Test", "6", "777"] 6: (3) ["Test", "7", "888"] I want to t ...

Uninstalling NPM License Checker version

Utilizing the npm license checker tool found at https://www.npmjs.com/package/license-checker The configuration in license-format.json for the customPath is as follows: { "name": "", "version": false, "description&quo ...

How to Ensure that the Hidden Value of Select Statement in Angular is Always Displayed as Text

Is there a way to customize the top part of a dropdown menu so that it always displays a specific phrase, like 'Symbols' in this case, regardless of the option selected? Currently, the top part shows the last selected symbol, but I want it to be ...