2

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 ?.

Bhimbim
  • 1,348
  • 2
  • 19
  • 15

3 Answers3

4

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.

tevemadar
  • 12,389
  • 3
  • 21
  • 49
  • what i'm going to is to map the values to object and then use the function predefined inside, not to parse a function. In .net this is possible with deserializeobject or in android also, so i guess i need to map manually inside :(. – Bhimbim Jun 19 '18 at 21:29
  • @Bhimbim I have just extended the answer with a possible workaround – tevemadar Jun 20 '18 at 18:34
3

JSON.parse is use to covert a valid JSON string data to JSON object. It will not convert functions to working JavaScript functions within a JSON object.

Please have a look at this link for futher details.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

Also if you apply/call this function on an existing object with one or more functions. It will replace existing object with object coming a string.

Zeeshan Elahi
  • 247
  • 2
  • 9
  • what i'm going to is to map the values to object and then use the function predefined inside, not to parse a function. In .net this is possible with deserializeobject or in android also, so i guess i need to map manually inside :(. – Bhimbim Jun 19 '18 at 21:29
3

You could have a look to this question: Parse JSON String into a Particular Object Prototype in JavaScript where the accepted answer suggests to use :

  • Object.assign(new Foo, { a: 1 })
  • Object.setPrototypeOf({ a: 1 }, Foo.prototype)
user1277186
  • 105
  • 5