Been working with Angular v1 for some time now and since Angular v2 came in Beta, been playing around with that.
Now I've got this piece of code, but can't get it to work, really don't know why. Somehow, when I print {{profileUser | json}}
everything works fine (profileUser is an object).
But when I want to print a child of that object (for example {{profileUser.name}}
or {{profileUser.name.firstName}}
), Angular throws the following error:
EXEPTION: TypeError: undefined is not an object (evaluating 'l_profileUser0.name') in [ {{profileUser.name}} in ProfileComponent@4:11
.
It's really confusing to me, should be just one of the simplest things around.. Just started with TypeScript btw..
Here is some code - ProfileService.ts
:
import { Injectable } from 'angular2/core';
import { Headers } from 'angular2/http';
import { API_PREFIX } from '../constants/constants';
import { AuthHttp } from 'angular2-jwt/angular2-jwt';
import 'rxjs/add/operator/map';
@Injectable()
export class ProfileService {
API_PREFIX = API_PREFIX;
constructor(private _authHttp:AuthHttp) {
}
getProfileData(username:string):any {
return new Promise((resolve, reject) => {
this._authHttp.get(API_PREFIX + '/users/username/' + username)
.map(res => res.json())
.subscribe(
data => {
resolve(data.data);
},
err => {
reject(err);
}
)
;
});
}
}
And here is my ProfileComponent
:
import {Component, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';
import {ProfileService} from '../../services/profile.service';
@Component({
selector: 'profile',
templateUrl: './components/profile/profile.html',
directives: [],
providers: [ProfileService]
})
export class ProfileComponent implements OnInit {
public username:string;
public profileUser:any;
constructor(private _profileService: ProfileService,
private _params: RouteParams) {
this.username = this._params.get('username');
}
ngOnInit() {
this.getProfileData(this.username);
}
getProfileData(username:string):void {
this._profileService.getProfileData(username)
.then(data => {
this.profileUser = data;
console.log(data);
})
;
}
}
Finally, the profile.html
template:
<pre> <!-- works! -->
{{profileUser | json}}
</pre>
or..
<pre> <!-- throws the error -->
{{profileUser.name | json}}
</pre>
or..
<pre> <!-- throws the error -->
{{profileUser.name.firstName}}
</pre>
FYI, the profileUser looks like this:
{
"id": "9830ecfa-34ef-4aa4-86d5-cabbb7f007b3",
"name": {
"firstName": "John",
"lastName": "Doe",
"fullName": "John Doe"
}
}
Would be great if somebody could help me out, this is really holding me back to get familiar with Angular v2. Thanks!
Angular throwError. RxJS throwError operator is used to create an Observable that emits an error notification immediately and no element. throwError can be used composing with other Observable, such as in a mergeMap, switchMap etc. throwError is introduced in RxJS 6 and we need to use it in place of Observable.throw ().
We use the CatchError to handle the errors thrown by the Angular Observable. Once we handle the error, we must return an observable. We can either return a replacement observable or return an error. The observable returned from CatchError is immediately subscribed.
Angular 6 has integrated RxJS 6 and Angular 6 onwards we can use throwError that will return Observable instance with error message. We catch error using catchError returned by throwError .
The error may be due to a network error or an error while executing the HTTP request or an exception thrown in an RxJS operator. These errors produce JavaScript ErrorEvent objects. The Angular assigns the ErrorEvent object to error property of the HttpErrorResponse.
In fact your profileUser
object is loaded from an HTTP request and it can be null
at the beginning. The json
pipe simply does a JSON.stringify
.
It's what your error message said: undefined is not an object (evaluating 'l_profileUser0.name')
.
You need to be sure that your profileUser
object isn't null to be able to get its name
attribute and so on. This can be done using an *ngIf
directive:
<div *ngIf="profileUser">
{{profileUser.name | json}}
</div>
When the data will be there, the HTML block will be displayed.
As Eric stated the Elvis operator could also help you. Instead of having {{profileUser.name | json}}
, you could use {{profileUser?.name | json}}
.
Hope it helps you, Thierry
It happens because when your controller is created, the profileUser
is undefined. And, when you use {{profileUser | json}}
the filter json
knows that you data is undefined and do nothing. When the profileUser
is finally defined, the angular updates thw whole thing and then profileUser | json
works. But, when you use {{ profileUser.anything | json}}
you will get an error because profileUser starts undefined
.
You can solve it, setting a empty profile to your variable at beginning of your controller, just like that:
profileUser = { name: {}};
This way, profileUser
never will be undefined
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With