I have a task of transforming array of type A into an an object with objects of class Person. I did it successfully but I can't invoke methods of class Person using transformed array. This is what I can't understand because all console.log checks shows that everything is transformed well and b contains exactly instances of class Person and not just arrays with data.
So my code is presented here:
import crypto from "crypto"
type A = Array<[string, number, string]>;
type B = {
[id: string]: Person
}
export class Person {
_id: string; // must be unique
age: number;
name: string;
city: string;
constructor(name: string, age: number, city: string) {
this._id = Person.generateUniqueID(12);
this.age = age
this.name = name
this.city = city
}
private static generateUniqueID(len: number): string {
return crypto.randomBytes(Math.ceil(len/2))
.toString('hex')
.slice(0, len);
}
public tellUsAboutYourself(): string {
console.log(
`Person with unique id = ${this._id} says:\n
Hello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.`
);
return `Person with unique id = ${this._id} says:\n Hello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.`
}
}
export const a: A = [
['name1', 24, 'city1'],
['name2', 33, 'city2'],
['name3', 61, 'city3'],
['name4', 60, 'city4']
];
export const b: B = a.reduce(function (value: any, [name, age, city]) {
let persona = new Person(name, age, city);
value[persona._id] = [persona.name, persona.age, persona.city]
return value;
}, {});
a successfully transforms to b, console log for b looks like this:
{
'd85750baf38f': [ 'name1', 24, 'city1' ],
'1f8fc00c6762': [ 'name2', 33, 'city2' ],
'8bac45ed719b': [ 'name3', 61, 'city3' ],
'1f00fa9086a2': [ 'name4', 60, 'city4' ]
}
console log for Object.keys(b) is:
[ 'd85750baf38f', '1f8fc00c6762', '8bac45ed719b', '1f00fa9086a2' ]
so how come when I do:
Object.keys(b).forEach(key => {
b[key].tellUsAboutYourself();
})
in tsc compiler it says:
exports.b[key].tellUsAboutYourself();
^
TypeError: exports.b[key].tellUsAboutYourself is not a function
CodePudding user response:
Your b
object is not having any instance of Person()
. You are just pasting in non-method properties.
As you can see below, any of the properties in b
is not having an object instance, but just an array.
{
'd85750baf38f': [ 'name1', 24, 'city1' ],
'1f8fc00c6762': [ 'name2', 33, 'city2' ],
'8bac45ed719b': [ 'name3', 61, 'city3' ],
'1f00fa9086a2': [ 'name4', 60, 'city4' ]
}
When you do the below, each property of b
will be a Person
instance and will have the method - tellUsAboutYourself
export const b: B = a.reduce(function (value: any, [name, age, city]) {
let persona = new Person(name, age, city);
value[persona._id] = persona;
return value;
}, {});
A better way to write your final loop can be using Object.values()
, so you directly have the individual values :
Object.values(b).forEach(obj => {
obj.tellUsAboutYourself();
})
but this is just an improvement.
CodePudding user response:
When you do
value[persona._id] = [persona.name, persona.age, persona.city]
inside de reduce, you are not saving the Person object, you are only putting its attributes on a array. This array won't have Person's methods. You should do
value[persona._id] = persona
instead.