2

I am trying to display some information which is fetched from an external API on a web page by using Angular's string interpolation.

When no information is fetched or hasn't "arrived" yet, I want to display 'N/A'.

I have tried the following approach, however I get an error saying: 'Can't read property 'name' of undefined' on line 2 of the following html code.

How can I show N/A while waiting for the response to be defined?

app.component.html:

<div id="api-info">
    {{ !!this.apiInfo.name ? this.apiInfo.name : 'N/A' }}
</div>

app.component.ts:

import { ApiInfo } from 'src/app/apiInfo.model'
import { ApiService } from 'src/app/api.service'
(...)
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
    apiInfo: ApiInfo;
    apiInfoSub: Subscription;

    constructor(apiService: ApiService) {}

    ngOnInit() {
        // apiService.apiInfo is a Subject<ApiInfo> where the API response is stored
        this.apiInfoSub = this.apiService.apiInfo.subscribe(
            (response) => {
                this.apiInfo = response;
            }
        );
    }

    ngOnDestroy() {
        this.apiInfoSub.unsubscribe();
    }
}

apiInfo.model.ts:

export class ApiInfo {
    public name: string,
    public id: number,

    constructor(name: string, id: number) {
        this.name = name;
        this.id = id;
    }
}

4 Answers 4

2

It is better to use async pipe, instead of subscribing and unsubscribing to stream manually. That makes the code cleaner and in the html use expression:

 {{(stream$|async)?.name || 'N/A'}}

Here is code sample: https://stackblitz.com/edit/angular-nknwuq

Sign up to request clarification or add additional context in comments.

1 Comment

This approach creates the subscription internally and unsubscribes automatically, which is great for avoiding memory leaks
2

I suggest to not subscribe within the component. Better use the async pipe instead and check as follows...

<div id="api-info" *ngIf="(apiInfo$ | async as apiInfo); else pending">
    {{ apiInfo.name }}
</div>

<ng-template #pending>
  n/a
</ng-template>

Which also allows you to style the n/a differently quite easy

Comments

1

please change your app.component.html to below:

<div id="api-info">
    {{ apiInfo?.name ? apiInfo.name : 'N/A' }}
</div>

this should resolve the issue.

Comments

1

apiInfo is undefined at start. The subscribe does not resolve immediately, so the apiInfo = response is set after some time. Maybe use <div id="api-info" *ngIf="apiInfo">

Or initialize on declaration: apiInfo: ApiInfo = <ApiInfo>{};

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.