Typescript serialize class objects

How do I serialize these classes in JSON?

As you can see from the example below, JSON.stringify() does not serialize the Cache_Backend_LocalStorage_Tag list inside the Cache_Backend_LocalStorage_TagThree object.

What am I missing?

 interface Cache_Backend_LocalStorage_Tag_Interface { _tag : string; _keys : string[]; } class Cache_Backend_LocalStorage_Tag implements Cache_Backend_LocalStorage_Tag_Interface { public _tag : string; public _keys : string[]; constructor(tag : string) { this._tag = tag; this._keys = []; } public add(key : string) : void { this._keys.push(key); } public remove(key : string): boolean { // Get the index of the key var index = this._keys.indexOf(key, 0); // Check if we found the keys index if (index != undefined) { this._keys.splice(index, 1); return true; } return false; } public get tag(): string { return this._tag; } public get keys(): string[] { return this._keys; } } interface Cache_Backend_LocalStorage_TagThree_Interface { _tags : Cache_Backend_LocalStorage_Tag[]; } class Cache_Backend_LocalStorage_TagThree implements Cache_Backend_LocalStorage_TagThree_Interface { public _tags : Cache_Backend_LocalStorage_Tag[]; constructor(tags : Cache_Backend_LocalStorage_Tag[] = []) { this._tags = tags; } public add(tag : Cache_Backend_LocalStorage_Tag) : void { this.tags[tag.tag] = tag; } public get tags(): Cache_Backend_LocalStorage_Tag[] { return this._tags; } public get(tagKey : string): Cache_Backend_LocalStorage_Tag { return this.tags[tagKey]; } public addKeyToTag(tagKey, key) { this.tags[tagKey].add(key); } public removeKeyFromTag(tagKey, key) { // Get the tag var tag = this._tags[tagKey]; // Check if we found the tag index if (tag != undefined) { return tag.remove(key); } return false; } public clear(tagKey : string): void { delete this._tags[tagKey]; } public static fromObject(object): Cache_Backend_LocalStorage_TagThree { return new Cache_Backend_LocalStorage_TagThree(object._tags); } } 

Question:

 var tagThree = new Cache_Backend_LocalStorage_TagThree(); tagThree.add(new Cache_Backend_LocalStorage_Tag("stores")); tagThree.addKeyToTag("stores", "store5"); tagThree.removeKeyFromTag("stores", "store5"); // {"_tags":[]} console.log(JSON.stringify(tagThree)); // { _tags: [ stores: { _tag: 'stores', _keys: [Object] } ] } console.log(tagThree); 
+6
source share
1 answer

Cause

This is because you are assigning properties to an array, and array properties will not be included in JSON serialization. For instance:

 var a = []; a["test"] = "some value"; JSON.stringify(a); // returns: [] 

You need to use a simple object:

 var o = {}; o["test"] = "some value"; JSON.stringify(o); // returns: {"test":"some value"} 

Decision

Change your Cache_Backend_LocalStorage_TagThree_Interface interface to use a dictionary, for example :

 interface Cache_Backend_LocalStorage_TagThree_Interface { _tags : { [tag: string] : Cache_Backend_LocalStorage_Tag; }; } 

Then update all areas of the code that will now have a compilation error to use the same type. For example, change:

 constructor(tags : Cache_Backend_LocalStorage_Tag[] = []) { 

To:

 constructor(tags : { [tag: string] : Cache_Backend_LocalStorage_Tag; } = {}) { 

Just for fun - changing the default serialization behavior (not recommended)

If you really want to do this work with an array with your current setting (I'm not sure why), you can override how serialization is done. To do this, add the toJSON method to the toJSON array in Cache_Backend_LocalStorage_TagThree . This allows you to control how the object is serialized when JSON.stringify is called on it. For instance:

 this._tags.toJSON = function() { var values = []; for (var v in this) { if (this[v] instanceof Cache_Backend_LocalStorage_Tag) { values.push(this[v]); } } return JSON.stringify(values); }; 
+4
source

Source: https://habr.com/ru/post/984142/


All Articles