Home > Blockchain >  Get Value from Interface is ending in "Cannot read properties of undefined (reading 'times
Get Value from Interface is ending in "Cannot read properties of undefined (reading 'times

Time:09-16

I am pulling information via an API from our system and want to output specific dates and information. The requesting and delivering is working fine:

{
    "id": "13963",
    "timestamp": "1631787752",
    "type": "cron",
    "rows": "0",
    "duration": "0"
}

My interface looks like this:

export interface StatusInterface {
    [key: string]: StatusElementInterface;
}

export interface StatusElementInterface {
    type?: string;
    lastrun?: Date;
    timestamp?: number;
}

I am requesting the information from the API in our class likewise:

dataArray = [
    "import",
    //"export",
    "cron",
    "delta"
];

dataResults = {} as StatusInterface;

In the constructor I am generating the arrays in this way:

for (var val in this.dataArray) {
    this.dataResults[val] = {} as StatusElementInterface;
}

In ngAfterViewInit I am running a loop in this way:

    for(var val of this.dataArray) {

        const requestUrl = `${href}?type=${val}`;

        this._httpClient.get<StatusInterface>(requestUrl)
          .pipe(
            map(data => {
              return data
            })
          )
          .subscribe(data => {

            // @ts-ignore
            this.dataResults[val] = data;
            console.log(this.dataResults[val]);
          }

The console output is correct and when I try to display it in the HTML file with dataResults["delta"] I get an [Object object] and when I try to do dataResults["delta"]["timestamp"] I get the error of an undefined property.

Can someone adjust me, what's running false or where my error is?

The Javascript log is

ERROR TypeError: Cannot read properties of undefined (reading 'timestamp')
    at StatusViewComponent_Template (status-view.component.html:18)
    at executeTemplate (core.js:9599)
    at refreshView (core.js:9465)
    at refreshComponent (core.js:10636)
    at refreshChildComponents (core.js:9261)
    at refreshView (core.js:9515)
    at refreshEmbeddedViews (core.js:10590)
    at refreshView (core.js:9489)
    at refreshComponent (core.js:10636)
    at refreshChildComponents (core.js:9261)

My template in the html looks so now:

        <mat-list-item>
            <mat-icon mat-list-icon>done</mat-icon>
            <div mat-line>Cronjob</div>
            <div mat-line *ngIf="cronTimestamp">Zuletzt beendet: {{ cronTimestamp | date:"dd.MM.yyyy HH:mm" }} Uhr</div>
        </mat-list-item>
        <mat-list-item>
            <mat-icon mat-list-icon>done</mat-icon>
            <div mat-line>Exportprozess</div>
            <div mat-line *ngIf="exportTimestamp">Zuletzt beendet: {{ exportTimestamp | date:"dd.MM.yyyy HH:mm" }} Uhr</div>
        </mat-list-item>
        <mat-list-item>
            <mat-icon mat-list-icon>done</mat-icon>
            <div mat-line>Deltaexport</div>
            <div mat-line *ngIf="deltaTimestamp; else loading">Zuletzt beendet: {{ deltaTimestamp | date:"dd.MM.yyyy HH:mm" }} Uhr</div>
        </mat-list-item>
        <mat-list-item>
            <mat-icon mat-list-icon>error</mat-icon>
            <div mat-line>Importprozess</div>
            <div mat-line *ngIf="importTimestamp">Zuletzt beendet: {{ importTimestamp | date:"dd.MM.yyyy HH:mm" }} Uhr</div>
        </mat-list-item>

I defined the getters like this:

get deltaTimestamp():number|undefined{
    if (this.dataResults['delta'] && this.dataResults['delta']['timestamp'] !== undefined)
        return (this.dataResults['delta']['timestamp'] * 1000);
    return (undefined);
}

get importTimestamp():number|undefined{
    if (this.dataResults['import'] && this.dataResults['import']['timestamp'] !== undefined)
        return (this.dataResults['import']['timestamp'] * 1000);
    return (undefined);
}

get exportTimestamp():number|undefined{
    if (this.dataResults['export'] && this.dataResults['export']['timestamp'] !== undefined)
        return (this.dataResults['export']['timestamp'] * 1000);
    return (undefined);
}

get cronTimestamp():number|undefined{
    if (this.dataResults['cron'] && this.dataResults['cron']['timestamp'] !== undefined)
        return (this.dataResults['cron']['timestamp'] * 1000);
    return (undefined);
}

Only the deltaTimestamp is getting shown.

Kind regards Henning

CodePudding user response:

just remove the // @ts-ignore it is ignoring your assignation.

now if it's in your html view that you have a problem, you may write dataResults?.delta?.timestamp because you have to wait till the object gets populated

still you will have problems if you do computation on the view side, on thing you could do is making a getter like:

get deltaTimestamp():number|undefined{
  if (this.dataResults['delta'] && this.dataResults['delta']['timestamp'] !== undefined)
    return (this.dataResults['delta']['timestamp'] * 1000);
  return (undefined);
}

then simply write deltaTimestamp in your view to access the value.

a more generic way that could work in ngFor* would be to use a function like getTimestamp(key) where you could access delta, cron and so on timestamp value.

  • Related