Nelson Teixeira
Nelson Teixeira

Reputation: 6610

Can't I use getters and setters in an Angular's httpclient result?

In my angular project I have a method that returns a User class from the backend:

export class User {
  id: string;
  name: string;
  my_list: Array<string>;

  get otherNameForMyList() : Array<string> {
    return this.my_list;
  }

  set otherNameForMyList(newList  : Array<string>) {
    this.my_list = newList;
  }
}

so I call the backend this way:

export class UserService {    
  getUserFromBE(login: string): Observable<User> {
    return this.http
      .get<User>(`${environment.apiUrl}/user/${login}`)
      .pipe(catchError(this.processHTTPMsgService.handleError));
  }
}

But when I call this method and subscribe the result I can't use otherNameForMyList:

let user = new User();
userService.getUserFromBE('mylogin').subscribe(async (u : User)=>{
  console.log(u.otherNameForMyList); // undefined
}

yet if I make it this way it works:

let user = new User();
userService.getUserFromBE('mylogin').subscribe(async (u : User)=>{
  console.log(u.my_list); // ok result
}

also console.log(u) returns Object type, not User type as it should be.

Now, if I declared the ": Observable" as result type from the httpclient call in getUserFromBE, shouldn't u be of User type ? Can I force it to be ?

Obviously the api is returning just my_list field.

Can anyone please explain why u is Object and not User ?

Thanks

Upvotes: 2

Views: 487

Answers (1)

Igor
Igor

Reputation: 62308

The generic methods on the HttpClient will use type assertion to on the deserialized json result. Example: .get<User> would still return an object but type assertion can now be used in the static code to treat that returned instance as a User. It does not mean the returned instance is of type User.

If you want an actual instance of User you should use map and create an instance of User to be returned to the caller.

Example:

export class UserService {    
  getUserFromBE(login: string): Observable<User> {
    return this.http
      .get<{id:string;name:string;my_list:Array<string>}>(`${environment.apiUrl}/user/${login}`)
      .pipe(map(user => {
        var result = new User();
        result.id = user.id;
        result.name = user.name;
        result.my_list = user.my_list;
        return result;
      }),catchError(this.processHTTPMsgService.handleError));
  }
}

Upvotes: 3

Related Questions