I have the weirdest problem.
I'm receiving a JSON object
{"login":"admin","name":"Admin"}
And what I'm doing in code is:
private _userData: User;
...
private getUserData() {
this._userInfoService.getUserInfo()
.subscribe(
data => {
this._userData = data.json(); // (using <User> data.json() changes nothing
},
err => alert(err)
);
}
Where User type is
export interface User {
login: string;
name: string;
}
But when I'm trying to access those fields in html with angular:
<p>{{ _userData.login }}</p>
<p>{{ _userData.name }}</p>
I'm getting some nasty errors in console like: Error: EXCEPTION: TypeError: l__userData21 is null in [{{ _userData.login }} in UserHomeComponent@8:7]
although I can clearly see when I'm doing console.log on this object: Object { login: "admin", name: "Admin" }
I did it exactly the same with other class and it works there. What is even more interesting is that when I slightly change the code, like this:
private _name: string;
private _login: string;
...
private getUserData() {
this._userInfoService.getUserInfo()
.subscribe(
data => {
this._name = (<User> data.json()).name;
this._login = (<User> data.json()).login;
},
err => alert(err)
);
}
and view:
<p>{{ _login }}</p>
<p>{{ _name }}</p>
Then everything works perfectly! I have absolutely no clue what is happening (tried to cast data.json() to but that changes nothing.)
@Edit: The other class, where it works is:
export interface LoginData {
access_token: string;
token_type: string;
refresh_token: string;
expires_in: number;
scope: string;
}
private _loginData = <LoginData> JSON.parse(sessionStorage.getItem("loginData")); //tried this also with User, doesn't work
and in the view:
<p>access_token: {{ _loginData.access_token }}</p>
<p>token_type: {{ _loginData.token_type }}</p>
<p>refresh_token: {{ _loginData.refresh_token }}</p>
<p>expires_in: {{ _loginData.expires_in }}</p>
the user data comes in asynchronously which means that it is undefined before. this is when angular will throw an exception because you do undefined .login
what you will have to do is to indicate that userData may be undefined by using the elvis-operator.
try this:
<p>{{ _userData?.login }}</p>
<p>{{ _userData?.name }}</p>
alternatively you can use a wrapping *ngIf for example
btw this has nothing to do with typescript, but with angular2 and javascript. please edit your title properly
You try to establish a databinding to _userData.login
and NOT to _userData
I see two possible errors:
First: - As Patrick already wrote, you data arrives asynchronously, which means _userData.login
is undefined when you try to establish the data-binding, because _userData
is undefined (and has no default null value). Therefore the data-binding fails and you won't be informed / get any updates when you later update it - Your second example works, how ever, because _name
and _login
are not undefined but filled with their NULL
value (I guess an empty string). Because of that the data binding is actually successfully estasblished
Second: - Second possible error is a binding of object references and object attributes. - Depending on how the change listener are implemented it is actually a difference between obj1 = newObject
and obj1.attr1 = newValue
. So changing just the object itself wouldn't trigger the change listener on a single attribute.
How ever, I'd bet it's the first possibility. You could test this by initializing the User
object with an empty object in the constructor...
Try adding something like this in front of the <p>
tags:
<div *ngFor="let uData of _userDat;">
and then
<p>{{uData.login}}
</p></div>
OR
<div *ngIf="user">
<p>{{_userDat.login}}</p>
Use ? for safe navigation.
<p>{{ _userData?.login }}</p>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.