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'}}})
Related
I would like to add new medication that contains "medc name, medc dose, medc dur"
I used update but the problem is the first argument. Im giving it a non-existing name so it adds it to the existing medications
the right syntax is "medication.avamys : medArr 'that contains the dose and dur'"
but this part "medication.avamys" is varying
so what can I do?
You will want to use the JavaScript syntax to use an expression as the property of an object.
...update({
["medication."+medcName]: medArr
})
Note the expression is in square brackets, and becomes the name of the field written to the document.
Note also that you are not required to build the object within the call to update(). You can build the object in a different statement, and pass it to update(). This is effectively the same thing, and probably more readable if you have lots of properties to assign:
const data = {}
data["medication."+medcName] = medArr
...update(data)
https://jsfiddle.net/snLxa8g1/
I'm passing an object as a prop to a component which then uses v-bind to insert all of the key-value pairs as attributes into a div element. In this example snippet, I pass { dataXyz: 'hey' }, which is then rendered lower-case in the DOM. How can I instead convert this CamelCase object notation to kebap-case with Vue (e.g. the attributes key becomes data-xyz in the dom)? Is there a Vue-specific helper function/method to accomplish this? The docs shortly mention Camel- and kebap-casing, but don't talk about any way I can convert the passed object to arrive as described :/
I found this useful code snippet for your use case
string
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
.replace(/([A-Z])([A-Z])(?=[a-z])/g, '$1-$2')
.toLowerCase();
Reference https://gist.github.com/nblackburn/875e6ff75bc8ce171c758bf75f304707#gistcomment-2874149
This jsfiddle might help you
https://jsfiddle.net/pwmuebnL/
In KnockoutJS, we can go
ko.mapping.toJS(object)
and get our object returned with observables and whatnot converted to vanilla Javascript object. Now, ko.mapping.toJS ignores computed properties. I have a scenario where I basically would like the functionality of ko.mapping.toJS to retain my pureComputed fields with whatever value they had at the time.
I've looked into the documentations page, but it looks like the "mapping options" are for the fromJS method, not toJS.
Any way I can convert my Knockout Object to a JS object but retain the pureComputeds being regular properties in the output?
I switched from ko.mapping.toJS to ko.toJS and the output of ko.toJS does include the computed properties like I want, so that seems to be all I need.
I want certain properties to be serialized as 'objects' and not strings. E.g.
{"onClickHandler": OnClickHandler,
"onMouseOut": OnMouseOutHandler}
The class def is like this:
public class handlers {
public string OnClickHandler;
public string OnMouseOutHandler;
}
Currently it comes out as:
handlers: {"onClickHandler": "OnClickHandler",
"onMouseOut": "OnMouseOutHandler"}
As you can guess, these are client side event handlers and correspond to javascript functions defined elsewhere. By emitting them within quotes, they are not interpreted as functions but as literal strings.
Edit:
Taking a cue out of Dave's answer, figured out a way:
first a little bit of scrubbing:
for (var handler in this.handlers) {
if(window[this.handlers[handler]])
this.handlers[handler] = window[this.handlers[handler]];
};
and then call jQuery bind normally
$elem.bind(this.handlers);
Accepting Dave's answer as that is closest.
JSON does not support representing functions. JSON consists of arrays of values, and objects (containing variables). Values in JSON can only be strings, numbers, objects or arrays (see the linked page for nice grammar diagram).
What you're after is javascript code, not a JSON object. If you're wanting to emit a reference to a function defined elsewhere, you may have to (shudder) use eval to execute it.
As someone else mentioned, that wouldn't be valid JSON anyway (which precludes you from using JSON.parse(), among other potential drawbacks).
If your event handler functions are defined in the global window scope, you could call them like this:
// This is equivalent to defining window.clickEventHandler or
// window['clickEventHandler'] as a function variable.
function clickEventHander() {
// Magic.
}
// Valid JSON, using strings to reference the handler's name.
var json = '{"onClickHandler": "clickEventHandler"}'
// You might be using eval() or a framework for this currently.
var handlerMappings = JSON.parse(json);
window[handlerMappings.onClickHandler]();
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.