user295541
user295541

Reputation: 1015

Angular TypeScript class instance

I have a typescript class:


 export class User {

    id: number;
    userName: string;
    knownAs: string;
    age: number;
    gender: string;
    created: Date;
    lastActive: Date;
    photoUrl: string;
    city: string;
    country: string;
    surname: string;
    givenname: string;

    get fullName(): string {
        return `${this.givenname} ${this.surname}`;
    }

    sayHello() {
        console.log(`Hello, my name is ${this.surname} ${this.givenname}!`);
      }
}

I have a Service function:



    user: User;
    this.userService.getUser(this.loggedUser.nameid).subscribe((user: User) => {
        this.user = user;
        this.user.givenname = this.loggedUser.given_name;
        this.user.surname = this.loggedUser.family_name;
        console.log(this.user.fullName);
        this.user.sayHello();
      });

the result in the console: console.log(this.user.fullName) = undefined this.user.sayHello(); = ERROR TypeError: Object doesn't support property or method 'sayHello'

After when I get back the user data from the server, how I can reach property and function which I've defined in the user class?

Upvotes: 0

Views: 2915

Answers (2)

Aragorn
Aragorn

Reputation: 5289

Try creating a prototype object for User like this. User you are getting from the service may not be a prototype object and hence the functions on it are not available.

user: User;
this.userService.getUser(this.loggedUser.nameid).subscribe((user: User) => {
    this.user = Object.assign(new User, user) //-->notice the use of new here..
    this.user.givenname = this.loggedUser.given_name;
    this.user.surname = this.loggedUser.family_name;
    console.log(this.user.fullName);
    this.user.sayHello();
  });

Update: JavaScript classes are not exactly an object oriented model. As per MDN:

JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.

Read more here

Also, as pointed out by @theMayer in comment, the service that returns user can also return the proper User object which has the prototype functions. So, its the displacement of code to create the object from the client to service. I like that approach, just because that means any other consumer of the service can use the object behaviors (functions), without having to duplicate (Object.assign)the object.

So, in the UserService.ts (or wherever that userService is defined), something like:

getUser(id: string):User {
  //existing logig
  return Object.assign(new User(), user)//--> there are other ways to create object too, this is just one way.
}

Upvotes: 1

Florian
Florian

Reputation: 1481

You're not creating an instance of User.
Here is an example of how it could be implemented :

 export class User {

    id?: number;
    userName?: string;
    knownAs?: string;
    age?: number;
    gender?: string;
    created?: Date;
    lastActive?: Date;
    photoUrl?: string;
    city?: string;
    country?: string;
    surname?: string;
    givenname?: string;

    constructor(args: User = {}) {
      this.id = args.id;
      this.userName = args.userName;
      this.knownAs = args.knownAs;
      this.age = args.age;
      this.gender = args.gender;
      this.created = args.created;
      this.lastActive = args.lastActive;
      this.photoUrl = args.photoUrl;
      this.city = args.city;
      this.country = args.country;
      this.surname = args.surname;
      this.givenname = args.givenname;
    }

    get fullName(): string {
        return `${this.givenname} ${this.surname}`;
    }

    sayHello() {
        console.log(`Hello, my name is ${this.surname} ${this.givenname}!`);
      }
}

Use map to create your User instance :

user: User;
this.userService.getUser(this.loggedUser.nameid)
  .pipe(map((user: User) => new User(user)))
  .subscribe((user: User) => {
    this.user = user;
    this.user.givenname = this.loggedUser.given_name;
    this.user.surname = this.loggedUser.family_name;
    console.log(this.user.fullName);
    this.user.sayHello();
  });

Upvotes: 0

Related Questions