Does anyone know of decent examples of custom JavaScriptConverter classes? The MSDN's only example is of one converting a ListItemCollection. What about custom classes? What if the custom class has a property of another custom class? Do we need two converters? Any references would be greatly appreciated.
Thanks!
You should only need one converter. The example basically outlines how to use the JavaScript converter for any custom class. It doesn't need to be a class that is part of the framework.
It will also work for any properties of a custom class that are themselves a custom class.
JSON views objects as collections of key/value pairs, so the documentation example shows how you should take any properties of your object and put them into Dictionaries (a type of Key/Value pair object). If you need a nested custom type, you can just nest Key/Value pairs inside of your main Key/Value pair collection.
Also, unless you have very specific needs (built-in serialization either won't work, or doesn't output what you want), you should just use the JavaScriptSerializer class.
JavaScriptSerializer serializer = new JavaScriptSerializer();
MyCustomObject obj = new MyCustomObject();
string json = serializer.Serialize(obj);
MyCustomObject object2 = serializer.Deserialize<MyCustomObject>(json);
That should do what you want in 95% of cases.
Related
How do I add new attribute to JSON object using JavaScript?
I want to add a new attribute to JSON object.
JSON stands for JavaScript Object Notation. A JSON object is really a string that has yet to be turned into the object it represents.
To add a property to an existing object in JS you could do the following.
object["property"] = value;
or
object.property = value;
If you provide some extra info like exactly what you need to do in context you might get a more tailored answer.
I have a React component state that holds many different classes that needs to be stringify()'d. Most of the components need to be specially treated before they can be put into the JSON object. I believe that using the replacer() and if statements to check the type and then modify the output would be too cumbersome. Short of creating a custom parsing system, is there a way to customize the stringify() in what it parses?
The idea would be to have a custom function (toString() for example) in each class that when the parser reaches the class, instead of going through the key-value pairs, would call the function and append it to the JSON object.
From JSON.stringify description
If the value has a toJSON() method, it's responsible to define what data will be serialized.
Usage
JSON.stringify({ toJSON() {return {a: 'eureka'}}})
Consider the following TypeScript class:
export class Spot {
public flight:number;
public dateAndTimes:Map<string,string>
public unitCost:number;
constructor(){
this.flight=0;
this.dateAndTimes= new Map<string,string>();
this.unitCost=0;
}
}
How can I convert the Spot object to JSON?
I try JSON.stringify(spot), but the attribute dateAndTimes it's serialized as empty... for example:
"spot": {
'flight':2,
{},
'unitCost':3500
}
Thank you very much!
Quoting from the MDN documentation for JSON.stringify:
All the other Object instances (including Map, Set, WeakMap, and WeakSet) will have only their enumerable properties serialized.
As a Map can have any type for keys and values then even if you were able to stringify it the JSON spec does not account for any types outside of "objects, arrays, numbers, strings, booleans, and null". Therefore if any of the keys or values of the Map are not of those types then it would not be allowed by the specification.
That last point is extremely important as even if a Map was somehow serialized to JSON but included any type of key or value not of the aforementioned allowed types then it is not determinable how a parser would process the resultant JSON back into an object. If it is not necessary to use a Map then I would recommend using a plain object for this to avoid this issue completely.
Note that it is also not possible to roll your own replacer function for the JSON.stringify method to handle that functionality.
In the Adobe Javascript DOM most objects classes have a plural class which contains all instances of that object e.g:
Hyperlink (an object for defining a hyperlink object)
Hyperlinks (an object for defining all instances of hyperlink objects)
Other than containing all instances of the singular object, the plural classes has its own properties and methods (so it is not an array).
This seems fairly straight forward to replicate within Javascript, however Adobe is able to use the following syntax:
var singleHyperlink = Hyperlinks[0];
They are able to treat the object as if it were an array. Passing it a numerator inside square braces will return a single objet.
How are they doing this?
I have written a NPAPI Plugin using firebreath framework. I am able to pass simple numeric values from Javascript and access them in my (C++)plugin, perform operations and then return the result. I would like to know how to operate on vectors now i.e arrays. I do not want to allocate new array inside my plugin and copy the array from JavaScript(Although I have no clue on how to do it). How can I directly access the JavaScript array in my plugin ? Is there a special way to do it ?
From the Firebreath website:
Javascript objects can be used with the FB::JSObjectPtr type. Examples of JavaScript objects that you may want to use include:
Javascript objects (with methods and/or value members)
Javascript Arrays (that you plan to modify; otherwise you can use a container type)
Javascript methods for callback
Arrays are objects; get values with getProperty(n) or getProperty("length") etc
You can also use methods like ->invoke("push", FB::variant_list_of(val)) etc
(on the JSAPI method in order to use the JSObjectPtr type you should use a method that looks something like:)
void doSomethingWithAnArray(const FB::JSObjectPtr& array) { ... }
Also remember that FireBreath can't tell what type of js object it is, just that there is a js object; you'll have to do your own error detection for the case where they don't give you an actual array but some other object instead.