Reputation: 5226
I have the following component and service:
Component
@Component({
selector: 'app-root',
template: '{{user.name}}',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
user: User;
constructor(private userService: UserService) {
this.userService.get().subscribe(user => {
this.user = user;
});
}
}
Service
@Injectable()
export class UserService {
constructor(private http: HttpClient) {
}
get(): Observable<User> {
return this.http.get<User>('http://www.mocky.io/v2/5cc0af9a310000440a0364b6');
}
}
User
export class User {
constructor(
public name: string
) {
}
}
As you can see, I'm just trying to print the user's name. It works, but before it prints the value I receive Cannot read property 'name' of undefined
error several times.
I know the reason — I load the user asynchronously, but how to deal with it?
I found the safe operator:
{{user?.name}}
And it works. But in my real project this approach will not work everywhere.
I also tried to use ngIf:
<div *ngIf="user">
{{user.name}}
</div>
But this will break another part of my app.
Is there a way to render a component after an HTTP call, so that I don't have to use Safe Operator or ngIf? If not, then what approach do you use? How do you deal with this problem?
Upvotes: 1
Views: 328
Reputation: 95
You don't need create a DTO for this case:
get(): any{
return this.http.get<User>('http://www.mocky.io/v2/5cc0af9a310000440a0364b6');
}
Upvotes: 0
Reputation: 9380
If you mean to say that by introducing another extra div in your template will break the CSS, you can use ng-container
element and have *ngIf
in that as
<ng-container *ngIf="user">{{user}}</ng-container>
According to the definition
The Angular is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
Upvotes: 0
Reputation: 22723
Your code looks correct, change your user class to interface:
export interface User {
name: string;
}
Or if you want to use the class, change it to:
export class User {
name: string;
}
You current code:
export class User {
constructor( public name: string) {
}
}
Means property will be created only when the constructor will be called, and that will only be called when you will try to create the object by using new:
user = new User();
Upvotes: 0
Reputation: 18975
You can prevent it by create default User
object
export class AppComponent {
user = new User('');
}
Upvotes: 0