0

I inherited some code in an Angular2 project which follows this pattern:

<input type="text [(ngModel)]="selectedResource.url">

The component constructor is as follows, where loadResources() is an async method that will initialize selectedResource:

constructor() {
    this.loadResources();
}

The problem I run into is that since selectedResource is null until the async method completes, the page loads and angular starts throwing a bunch of errors complaining that selectedResource is null, until the async method completes, and then everything works great.

To avoid the exceptions I see two solutions - first, change the html to the following which will tell angular to check for null.

<input type="text [ngModel]="selectedResource?.url" (ngModelChange)="selectedResource.url = $event">

Alternatively I could initialized selectedResource in the page constructor. Url would initially load on the page as an empty string, but that's okay since the async method runs almost instantaneously and the user wouldn't notice.

constructor() {
    this.selectedResource = new Resource();
    this.loadResources();
}

Is there an established best practice for initializing data bound variables? What would be the advantages or disadvantages of each approach?

1 Answer 1

1

Use safe navigation operator ?. to wait for the asynchronous event to complete.

<input type="text [ngModel]="selectedResource?.url" (ngModelChange)="selectedResource.url = $event">

When to use safe navigation operator?

If you are accessing the asynchronous object inside the template, then you really don't have to initialize the object to empty. Because ?. is meant for that(which does not work in .ts file or class). If you were accessing it inside the component (.ts), for null check before it has the data, then you probably have to initialize it to empty object.

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

5 Comments

Yes, I put that exact line of code in the question. I am not asking how to avoid the exception. I am asking for best practice and what the advantage or disadvantage of different approaches are.
Your code does not show any usage of ?. operator. And that is the best way to handle asynchronously loaded object.
Ah my mistake, typo. Can you explain what makes it the best way to handle it versus initializing to empty?
Well if you are accessing it inside the template, then you really don't have to initialize it to empty. Because ?. is meant for that(which does not work in .ts file or class). If you were accessing it inside the component (.ts), for null check before it has the data, then you probably have to initialize it to empty object.
Ultimately, its very rare that you check for null inside the component, before it has the data. Because you know when it will be set. So in my opinion, it is not required to initialize to empty. Of course, its your choice. There is no harm even if you initialize.

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.