Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function in object become not a function after JSON.parse

I have model let say like this :

export default class UserObject
{
    name: string;
    id: string;

    validateInsert()
    {

    }
}

If i do like this :

const modelUser: UserModel = new UserModel();
modelUser.ID = 1;
modelUser.Name = "Ibrahim Aziz";
modelUser.validateInsert();

everythings work fine, but if i do it like this :

modelUser = JSON.parse(stringJSONUser);
modelUser.validateInsert();

I will get error saying validate insert is not a function, it seems that JSON parse only pass the value, not even initiate the object it self, any idea ?.

like image 415
Bhimbim Avatar asked Jun 21 '26 10:06

Bhimbim


1 Answers

You may want to visit json.org, it has a very compact description about what JSON has.

In short:

  • objects (in the sense of key-value pairs, so they are associative-arrays / maps / dictionaries, but they are not "OOP objects" with constructors, methods and the like)
  • arrays (list of values)
  • strings
  • numbers
  • true
  • false
  • null

"function" is not in the list, there are no functions in JSON.

You will need a workaround, perhaps what another answer suggests, or something else.


While I do not know TypeScript, you may get some idea from the following JavaScript example:

class UserObject{
  constructor(name,id){
    this.name=name;
    this.id=id;
  }

  validateInsert(){
    return this.name.length>0 && this.id!=0;
  }
}

var originalUser=new UserObject("tevemadar",123);
console.log("original:",originalUser.name,originalUser.id,originalUser.validateInsert());

var json=JSON.stringify(originalUser);
console.log("json:",json);

var failUser=JSON.parse(json);
try{
  console.log("fail:",failUser.name,failUser.id,failUser.validateInsert());
}catch(ex){
  console.log("failUser failed:",ex.toString());
}

var correctUser=JSON.parse(json,function(key,value){
  if(typeof value==='object')
    return Object.assign(new UserObject,value);
  return value;
});
try{
  console.log("correctUser:",correctUser.name,correctUser.id,correctUser.validateInsert());
}catch(ex){
  console.log("correctUser failed:",ex);
}

JSON.parse has an optional second argument too, which can do transformations to all the 'things' restored from JSON. In the 'correctUser' part of the example above every single 'thing' is checked for being an object, and if it is an object, it is 'cast' to UserObject and thus gets the missing function (while there is no real casting in JavaScript at least as far as I know, Object.assign makes creating a proper object and filling its fields simple. I think you will need to do the same in TypeScript too, as type assertions say they do not actually do anything to the object).

The catch is that here every single object is going to be UserObject, so if you have multiple classes, you would have to tell them somehow apart (perhaps via checking what fields they have), and create the replacement object accordingly.

like image 97
tevemadar Avatar answered Jun 24 '26 00:06

tevemadar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!