I have an API, that returns me the Profile
info and I am fetching it in my HTTP service. The nested object User
has a method getRole()
. But when I am trying to call this method, I get
ERROR TypeError: _co.profile.user.getRole is not a function
When I fetch User
from my other service, that only returns the User
entity, I am able to call this function no problem.
What am I missing ?
Model
export class Profile {
user: User;
apiKeys: ApiKey[];
}
export class User {
user: string;
firstname: string;
surname: string;
email: string;
role: Role;
active: boolean;
getRole() {
switch (this.role) {
case Role.READ: {
return "READ";
}
case Role.WRITE: {
return "WRITE";
}
case Role.ADMIN: {
return "ADMIN";
}
default : {
return "READ";
}
}
}
}
ProfileService.ts
getProfile(): Observable<Profile> {
return this.http.get<Profile>(this.profileUrl).pipe(catchError(this.handleError));
}
Component.ts
profile: Profile;
isProfileAvailable:boolean = false;
ngOnInit() {
this.settingsService.getProfile().subscribe(profile => {
this.profile = profile;
this.isProfileAvailable = true;
});
}
Component.html
<p-fieldset [legend]="Profile" *ngIf="isProfileAvailable">
<div><b>User: </b>{{profile.user.firstname}}</div>
<div><b>E-mail: </b>{{profile.user.email}}</div>
<div><b>Role: </b>{{profile.user.getRole()}}</div>
</p-fieldset>
Calling http.get<Profile>
does not automatically initialize an object of type Profile
, therefore the property user
is also not an object of type User
and has not got the method getRole
.
You can use Object.assign to initilize objects and it's properties. And because there are two class types (Profile
, User
), both can extend from a Base
-Class to handle the assignation of the properties for both types.
Models:
// Use a Base class to assign all properties with objects both of type Profile and User
class Base {
constructor(properties?: any) {
(Object as any).assign(this, properties);
}
}
export class User extends Base {
user: string;
firstname: string;
surname: string;
email: string;
role: Role;
active: boolean;
getRole() {
switch (this.role) {
case Role.READ: {
return "READ";
}
case Role.WRITE: {
return "WRITE";
}
case Role.ADMIN: {
return "ADMIN";
}
default : {
return "READ";
}
}
}
}
export class Profile extends Base {
user: User;
apiKeys: ApiKey[];
// take advantage of Object.assign
// to initialize an instance of type Profile
// along with it's property user
constructor(properties?: any) {
super(properties);
this.user = new User(properties.user);
}
}
ProfileService.ts
getProfile(): Observable <Profile> {
return this.http.get<Profile>(this.profileUrl).pipe(catchError(this.handleError));
}
Component.ts
profile: Profile;
isProfileAvailable:boolean = false;
ngOnInit()
{
this.settingsService.getProfile().subscribe(profileData => {
// assuming that profileData looks like this:
/*
{
user: {
user: 'user',
firstname: 'firstname',
surname: 'surname',
email: 'email',
active: true
}
}
*/
this.profile = new Profile(profileData);
this.isProfileAvailable = true;
});
}