P. Aiello
P. Aiello

Reputation: 127

Angular 4 and MVC data binding error

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

Answers (2)

David Walschots
David Walschots

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

Saksham Gupta
Saksham Gupta

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

Related Questions