Reputation: 12960
I have a ton of models that I have always been structuring like so:
interface IPerson {
firstName: string;
lastName: string;
fullName: string;
}
class Person implements IPerson {
public firstName: string;
public lastName: string;
public fullName: string;
constructor(_firstName: string, _lastName: string) {
this.firstName = _firstName;
this.lastName = _lastName;
this.fullName = `${this.firstName} ${this.lastName}`;
}
}
I then eventually call some api to return some json.
Example Response:
{
"data": [
{
“firstName”: “John”,
“lastName”: “Doe”
},
{
“firstName”: “Jane”,
“lastName”: “Doe”
}
]
}
After I get the response, I would then just 'new it up' by doing something simple like:
return response.data.map( d => new Person(d.firstName, d.lastName));
My question:
I have some models that have quite a large set of properties and is seems extremely redundant to pass them in as parameters and bind them to the respective properties (at least that's what it feels like). Is there a more elegant way of doing this?
I see a lot of things that are similar to the below examples, but none of them seems to actually 'new up' the object in the class so it behaves correctly (ie: concatenating firstName and lastName).
Similar articles seems to mention something like this:
var modal: IModal = {
content: '',
form: '',
href: '',
$form: null,
$message: null,
$modal: null,
$submits: null
};
other mention something along the lines of this:
modal: IModal = <IModal>{}
or
var modal = {} as IModal
Upvotes: 1
Views: 653
Reputation: 2621
You can use Object.assign
in order not to list properties every time, but instead use data object itself. - example
UPDATE: declared a filter function to remove properties that not are not part of the class from source data. But there is drawback, that class properties have to have initial values in order them to appear in compiled javascript code. If they don't have initial values typescript class will be compiled empty, and there will no way of getting list of properties of typescript class in runtime.
function filter(obj, data) {
return Object.getOwnPropertyNames(obj).reduce((acc, k) => {
acc[k] = data[k];
return acc;
}, {})
}
class Person implements IPerson {
public firstName: string = "";
public lastName: string = "";
public get fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
constructor(data) {
Object.assign(this, filter(this, data))
}
}
Upvotes: 2
Reputation: 725
Write a constructor that takes an IPerson
interface IPerson {
firstName: string;
lastName: string;
fullName: string;
}
class Person implements IPerson {
public firstName: string;
public lastName: string;
public fullName: string;
constructor(_firstName: string, _lastName: string) {
this.firstName = _firstName;
this.lastName = _lastName;
this.fullName = `${this.firstName} ${this.lastName}`;
}
public static fromIPerson(person: IPerson): Person {
return new Person(person.firstName, person.lastName);
}
}
Upvotes: 3