0

I am trying to open a model that will display information from another component. I'm injecting the data into the child component, but I'm getting an error. I was wondering whether it's because the array I'm injecting is sometimes null.

ERROR TypeError: Cannot read property 'open' of undefined
    at StarshipComponent.openPilots (main.js:97)
    at StarshipComponent_mat_card_0_Template_button_click_12_listener

This is parent component

import { Component, OnInit, Input } from '@angular/core';
import {SwapiService} from "../../models/swapi.service";
import {Pilot, Starship} from "../../models/starship";
import {ActivatedRoute} from "@angular/router";
import {MatDialog, MatDialogConfig} from "@angular/material/dialog";
import {PilotsComponent} from "../pilots/pilots.component";
// import {Location} from "@angular/common";


@Component({
  selector: 'app-starship',
  templateUrl: './starship.component.html',
  styleUrls: ['./starship.component.css']
})
export class StarshipComponent implements OnInit {
  // public starship: Starship;
  public name: string;
  public pilots: Pilot[];
  public selectedStarship: Starship
  private dialog: MatDialog;
  private openPilotVariable = {display: 'none'};
  showButton = {display: 'inline-block'};




  constructor(private swapi: SwapiService,
              private route: ActivatedRoute) {
    this.name = this.route.snapshot.paramMap.get('name');
     }

    ngOnInit(){
    // this.loadStarship();
  this.swapi.apiData.subscribe(data => {
    console.log('subscribed data', data);
    this.selectedStarship = data.find(starship => starship.name == this.name);
    // console.log(this.selectedStarship);
    console.log(this.selectedStarship.pilots);

  })
  }

  openPilots(): void {
    this.openPilotVariable.display = 'block';
    const dialogConfig = new MatDialogConfig();

    dialogConfig.disableClose = false;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '600px';
    dialogConfig.data = this.selectedStarship.pilots;
    // dialogConfig.data = {
    //   starship: this.selectedStarship,
    // };
    // console.log(this.selectedStarship.pilots);

    this.dialog.open(PilotsComponent, dialogConfig);

  }


  // backClicked() {
  //   this.location.back();
  //   // console.log(this.location);
  // }


}

this is the parent template

<!--<button mat-stroked-button color="primary" [ngStyle]="{'margin':'1rem 2rem'}" (click)="backClicked()">Back</button>-->
<mat-card class="card" *ngIf="selectedStarship">
    <mat-card-title>StarWar Details</mat-card-title>
      <mat-card-subtitle>Name of Starship: {{selectedStarship?.name}}</mat-card-subtitle>
      <mat-card-subtitle>Model: {{selectedStarship?.model}}</mat-card-subtitle>
      <mat-card-subtitle>Manufacturer: {{selectedStarship.manufacturer}}</mat-card-subtitle>
      <mat-card-subtitle>Cost In Credits: {{selectedStarship.cost_in_credits}}</mat-card-subtitle>
  <mat-card-actions>
    <button mat-raised-button type="submit" color="warn" (click)="openPilots()" [ngStyle]="showButton">More info on Pilots</button>
  </mat-card-actions>
</mat-card>

this is the child component

import {Component, Inject, OnInit} from '@angular/core';
import {Pilot, Starship} from "../../models/starship";
import {SwapiService} from "../../models/swapi.service";
import {ActivatedRoute} from "@angular/router";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";

@Component({
  selector: 'app-pilots',
  templateUrl: './pilots.component.html',
  styleUrls: ['./pilots.component.css']
})
export class PilotsComponent implements OnInit {
  // public starship: Starship[];
  public pilots: Starship;
  public name: string;

  constructor(public dialogRef: MatDialogRef<Starship>,
              @Inject(MAT_DIALOG_DATA) data,
              private swapi: SwapiService,
              ) {
    console.log(data);
    // console.log(this.pilots);
  }

  ngOnInit(): void {

  
  }

  closeDialog(): void {
    setTimeout(() => {
      this.dialogRef.close();
    }, 2000);

  }

}

I don't have a template for the child yet, but I get an error just by click on the button. Please note that I see the array from the parent component, and when it's null, I see []. but I'm not able to pass it correctly. Could I be getting the error because I'm trying to pass an array?

Heidi E
  • 221
  • 8
  • 22
  • Perhaps I'm not the one to ask for help about this, but umm... What language is this? I'm not sure if I'm seeing some new features that were recently added to C++ or is it just Java. (I've never actually used Java.) – Caston Nov 20 '20 at 02:47
  • 1
    it's angular. a JS framework – Heidi E Nov 20 '20 at 02:53

1 Answers1

1

It seems you are not inject matdialog in your parent component.

StarshipComponent.ts

constructor(private swapi: SwapiService, private route: ActivatedRoute, private dialog: MatDialog) {
  this.name = this.route.snapshot.paramMap.get('name');
}

instead of

constructor(private swapi: SwapiService, private route: ActivatedRoute) {
  this.name = this.route.snapshot.paramMap.get('name');
}

Ref: https://stackblitz.com/angular/yjjeryedojbp?file=src%2Fapp%2Fdialog-overview-example.ts