Search code examples
javascriptangularangular11

TypeError: Cannot read property 'commit' of undefined Angular


I have an Angular project that picks up the parameters from a Spring Boot project. In the back I have a DTO that contains the information and from the front I access that information to display it on the screen. When I show the dialog with the information it shows an error in the console TypeError: Cannot read property 'commit' of undefined, but it works fine.

This is the error:

enter image description here

This es the about.component.html:

<header class="title-color" fxFlex>Build Info</header>
<mat-divider></mat-divider>
<span class="header-item">Front (Angular): </span>
<div fxFlexLayout="column" class="about-data">
    <div>Commit: {{data.front.commit}}</div>
    <div>Fecha: {{data.front.date}}</div>
    <div>Versión: {{data.front.version}}</div>
</div>
<mat-divider></mat-divider>
<span class="header-item">Back (Java): </span>
<div fxFlexLayout="column" class="about-data">
    <div>Commit: {{data.people.commit}}</div>
    <div>Fecha: {{data.people.date}}</div>
    <div>Versión: {{data.people.version}}</div>
</div>

This is the about.component.ts:

ngOnInit() {

    this.http.get('/assets/build_info.txt', { responseType: 'text' }).subscribe((data: String) => {

      let re: RegExp = new RegExp("^(Author|Date|commit|Version).*", "i");
      let frontInfo: InfoDTO = data.split('\n').filter(l => re.test(l)).reduce((accum, line) => {
        line = line.replace(":", " ");
        let sepIndex = line.indexOf(' ');
        let attr = line.substring(0, sepIndex).toLowerCase();
        let value = line.substring(sepIndex).trim();
        accum[attr] = value;
        return accum;
      }, new InfoDTO());

      const ob1 = this.aboutService.aboutInfo();

      ob1.subscribe((people: InfoDTO) => {
        this.data = {
          front: frontInfo,
          people: InfoDTO
        };
      });
    });
  }

I can't find what the problem could be because the data is all right and I don't know what causes that error.


Solution

  • You are trying to display a data that is not yet fetched. fetch (and so the subscribe) is asynchronous, therefore your view is displayed before the data is available.

    There is multiple solution to this, you can for example add a condition in your view like :

    <div *ngIf="data?.front"> 
      ... display your data here 
    </div>
    

    And same for data.people. Depending on how you are initialising data, you could even wrap your whole code in *ngIf="data" condition.

    So, with your code, it would looks like :

    <header class="title-color" fxFlex>Build Info</header>
    <mat-divider></mat-divider>
    <span class="header-item">Front (Angular): </span>
    <div *ngIf="data?.front" fxFlexLayout="column" class="about-data">
        <div>Commit: {{data.front.commit}}</div>
        <div>Fecha: {{data.front.date}}</div>
        <div>Versión: {{data.front.version}}</div>
    </div>
    <mat-divider></mat-divider>
    <span class="header-item">Back (Java): </span>
    <div *ngIf="data?.people" fxFlexLayout="column" class="about-data">
        <div>Commit: {{data.people.commit}}</div>
        <div>Fecha: {{data.people.date}}</div>
        <div>Versión: {{data.people.version}}</div>
    </div>