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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.