The original proto object is missing in JSON.parse
The Problem ๐ : Check the code given below ๐
class Student {
constructor(private firstName: string, private lastName: string) {}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
const student = new Student("Virendra", "Patel");
console.log(student.getFullName()); // Virendra Patel
const stringStudent = JSON.stringify(student);
const parsed = JSON.parse(stringStudent); // parsed will firstName and lastName
console.log(parsed.getFullName && parsed.getFullName()); // undefined
Did you get the issue ๐ค
No? ok, let's understand.
We have created a class Student
, and then we have created an object of the Student
class and calling the getFullName
method on the student object, prints the full name on the console.
But ๐ง
when we are converting that student object to JSON using JSON.stringify(student)
and parsing the JSON to object using JSON.parse(stringStudent)
, calling the getFullName
method on the parsed object, prints the undefined on the console.
Why? ๐คฏ
whenever we use JSON.parse(stringStudent), It will return an object after parsing the JSON, which will have Object.prototype
in the __proto__
of the parsed object, and when you access getFullName()
using the parsed object, that will be there in the __proto__
How to solve ๐คจ
Simple, set the Student.prototype
to the parsedObject.__proto__
How ๐
Object.setPrototypeOf(parsedObject, Student.prototype)
Check out the code below which has a custom parse method in Student
class.
class Student {
constructor(private firstName: string, private lastName: string) {}
static parse<T>(json: string): T {
const students = JSON.parse(json);
if (Array.isArray(students)) {
students.forEach((student) => {
Object.setPrototypeOf(student, Student.prototype);
});
return students as T;
}
return Object.setPrototypeOf(students, Student.prototype) as T;
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
const students = new Student("virendra", "Patel");
const string = JSON.stringify(students);
const parsed = Student.parse<Student>(string);
console.log(students.getFullName());
console.log(parsed.getFullName && parsed.getFullName());