Reputation: 127
I've a problem with Angular 4 and data binding. I've a 2 classes, once for the model and one for the service.
Model:
export class User{
public id:number;
public name:string;
public surname:string;
public email:string;
public password?:string;
constructor(id?:number, name?:string, surname?:string, email?:string, password?:string){
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
this.password = password;
}
}
Service:
import { Injectable } from "@angular/core";
import { User } from "../model/user";
import { PhpService } from "../cms-pages/php.service";
@Injectable()
export class UserService {
constructor(private _http: PhpService){}
getCurrentUser():User{
let user:User = new User();
this._http.get("user/self").subscribe(res =>{
let data = res['data'];
console.log(data['name']);
user = new User(
data['id'],
data['name'],
data['surname'],
data['email']
);
console.log(user);
});
return user;
}
}
In the component file I've:
public currentUser:User = new User();
ngOnInit() {
this.currentUser = this._user.getCurrentUser();
}
And into the HTML file I've:
<span class="nav-text" style="padding-right: 12px !important; padding-left: 5px !important; font-size: 16px;">
{{currentUser['name']}}<br>{{currentUser['surname']}}
</span>
When I access the page in the console it appears:
Can not read property" name "of undefined
Can someone help me?
EDIT: the method for post request is:
post(url, headers, parameters): Observable<any>
{
return this.http.post(url, '', {headers: headers, body: parameters})
.map(message => this.interceptMex(message))
.catch( error => Observable.of( this.interceptMex(error)))
.finally(() => this.stopLoader());
}
Upvotes: 0
Views: 88
Reputation: 12680
Use RxJS's Observable
in combination with the map
function:
getCurrentUser(): Observable<User> {
return this._http.get('user/self').map(res => {
const data = res['data'];
return new User(data['id'], data['name'], data['surname'], data['email']);
});
}
ngOnInit() {
this._user.getCurrentUser().subscribe(user => this.currentUser = user);
}
Error handling (if any) should be passed as the second argument to the subscribe
function.
Within your view, bind using the safe navigation operator as follows:
<span>
{{currentUser?.name}}<br>{{currentUser?.surname}}
</span>
Or alternatively wrap nodes that display data of currentUser
with *ngIf
:
<span *ngIf="currentUser">
{{currentUser.name}}<br>{{currentUser.surname}}
</span>
Upvotes: 3
Reputation: 628
Your api call is async so by the time it fetches the response the user object is returned. Use promise instead.
getCurrentUser(): any {
let user:User = new User();
return new Promise((resolve, reject) => {
this._http.get("user/self").subscribe(res =>{
let data = res['data'];
console.log(data['name']);
user = new User(
data['id'],
data['name'],
data['surname'],
data['email']
);
resolve(user);
}, err => {
reject(err);
});
})
}
And in your component
ngOnInit() {
this._user.getCurrentUser().then((user) => {
this.currentUser = user;
}).catch((err) => {
console.log(err)
});
}
Upvotes: 1