Serializing business objects as JSON - javascript

I'm trying to serialize my business objects into JSON for consumption by a Javascript application. The problem is is that I'm trying to keep my business objects "pure" in the sense they are not aware of data access or persistence. It seems to me that "diluting" my objects with a toJSON() function would go against this goal. On the other hand, using an external object to serialize my business objects would not work since I keep all my instance variables private.
Am I approaching this totally the wrong way?

If the instance variables are private, they should not appear in a serialization that is being sent to a JavaScript application. By definition, if you're serializing them and sending them to a separate application, they are public. So, an external object should have some way of accessing them, probably through some sort of getter methods.

What purpose does searializing the data in JSON serve? Is it purely for reporting? If so, then Brian is correct, those variables should have getter methods.
If the purpose of serialization is to transport the data to a JavaScript app where it can be manipulated and then returned to the originating application, then perhaps you would be best served by creating a related class that serves the purpose of serialization while still maintaining strong encapsulation.
For example, in Java you could define an inner class. An inner class instance has direct access to all fields of the enclosing class instance without the need of getter methods. Or you could group with a package (or namespace) using the correct access modifiers to permit access by the serializer, but not by any other class.
Or you could use reflection. Or hijack the toString method. (Or shine it all and create a toJson method.)

Are you thinking of generating JSON from non-javascript code (like server-side Java)? The answer kind of depends on that: handling of JSON is quite different on Javascript and, say, Java. There's already an answer wrt javascript-side, which seems correct.
If this is on Java, there are libraries that can help; for example (Jackson) can deserialize any bean, using regular getX/setX method introspection; plus additional (and optional) annotations.

Related

Use plain Javascript object as Ember model

Is it possible to use a plain JS object (say literal object) as model in EmberJS ?
All the examples that I see in the documentation use Ember.Object (or datastore)
I assume I might not get things like observable, etc using plain JS. But is it at least supported ?
This will not work reliably. A template such as
{{model.prop}}
operates by putting an observer on 'model.prop'. This might work in some cases, but not in others, or you may get weird Ember messages.
Of all the aspects of Ember, the most basic is the Ember object model. Essentially, the entire framework is based on this model and using it to manage objects and retrieve and set properties. Once you've bought into Ember, you've bought into using this object model, which is based on old-fashioned classic inheritance.
A common case where your issue comes up is that a server API returns a plain old JS object as the value of a model property. You then want to dig around inside that object, or display its properties in templates. In such cases, it is probably best to either convert the object to an Ember Object (you can do this with transforms; google and you will find people doing this); or, use embedded models, which is not trivial to do, and may require server-side changes (such as including an ID in the embedded models, although you could theoretically add one yourself in the adapter). The latter is what I have done and the end result was to pretty much maintain my sanity.

Using Angular, where should I store my constants?

This question has less to do with how to do something, but more about best practices and what do others do?
I have a few services where I am using some kind of an external API (in this case the session storage api in the browser), where I am reusing the same constant string, the name of the company and the application, let's call it "ACME.Storage.", and this I want to prepend at the start of every "key" string. I see my options as:
I can just reuse the string "ACME.Storage." in every call.
I can create a JavaScript function where I create a new storage object that is configured with "ACME.Storage." once. That way, "ACME.Storage." appears once in my code.
I can create a local variable ans store "ACME.Storage." in it, then reuse that. Again, the string literal appears only once in my code.
I can create a separate javascript object that I can share.
I can use an AngularJS "constant"
I can add as a field to the app of config file.
I can store it somewhere where localized literal strings (even though this particular string isn't localized) and get it through a translation service.
I'm leaning toward using the "constant" service 'cause it's the one that's easily injectable. My only concern is that it's less encapsulated than some of the other options.
Opinions on the best practice?
To expand upon what Whishler posted, you can (and probably should) use the Constant module that Angular provides. Complete docs are found here: http://docs.angularjs.org/api/ng/type/angular.Module. Services are a common place for constants, but the Constant modules get applied before other provide methods. Another option would be Value, but it does pretty much the same thing.
Generally, I put constants into a service.
Depending what I'm doing, I may create a service that does nothing but store related constants. Or I may add them to another service representing a 'model'.
I'll also add that JavaScript doesn't officially have constants; so unless you wrote some code--such as your own accessors--you're just dealing with a variable that could be changed during the execution.

JS: Serializing an object with methods (or an instance) to json/string without losing the methods

Bumped into this while trying to cache objects into localstorage. seems that localstorage currently doesn't support objects with methods/object Instances etc. just POJO that are serialized into a string. In python there's pickle that can handle this (or marshal before it) but I couldn't find a js equivalent. Since I guess I'm not the first Js dev to need this feature I guess there are already proven solutions (either in patterns or external libs) to this problem which I'm missing.
Basically I'm looking for a way to call serialize(object) into a json/string and later deSerialize(objString) that would return the original object/instance etc.
The answer can be some lib and doesn't have to be part of the js standard library.
I use JSONfn do that. It has its own stringify/parse methods that save functions as well as ordinary JSON data.

Cleanest way to make a proxy/passthrough for a JavaScript object that can be called from Dart

This is admittedly weird, but bear with me:
I'm using Dart's js-interop package so that I can call from Dart into JavaScript.
The system I have to work with has a communication path via a particular global JavaScript object - this object is inserted into the JavaScript context as a way to call into native code, but it's not a true JavaScript object; it's a little hacky.
I can't make a Dart Proxy directly to this object because the Proxy code depends on certain constructors and aspects of the prototype chain that don't exist for this hacky object. Specifically, the JsObject_JsObject function generated by dart2js tries to call "constr.bind.apply" where constr is the constructor of the JS object. This object doesn't have a .bind property since it doesn't inherit correctly from other stuff, and all my attempts to add/fix the prototype chain have failed so far.
If I could fix that, it'd be great. But my other option is to proxy a proxy - make a true Javascript object that wraps and proxies the wacky-hacky-native-object, then a Dart Proxy for that.
I'm curious what the cleanest way to make that JS proxy would be - I'd like to call various functions from Dart, with varying numbers of parameters, and have the calls pass through cleanly to the native object, without having to constantly maintain my JS proxy by making sure any functions added to the native object are added to the proxy.
Does anybody have any great/creepy ideas to make this proxy idiot-proof so that it doesn't need a lot of maintenance, but just automagically redirects calls to the native object?
constr.bind.apply is only call on Js Object creation from Dart. You can simply make a JS function that creates your particular JS Object (for instance createWtfObject()). Once created on JS side (by calling from Dart context.callMethod('createWtfObject')) you should be able to use it without problem from Dart side.

Performance of key lookup in JavaScript object

I just read this question: are there dictionaries in javascript like python?
One of the answers said that you can use JavaScript objects like Python dictionaries. Is that true? What is the performance of a key lookup in an object? Is it O(1)? Is adding a key to the object also constant time (hashing)?
The V8 design docs imply lookups will be at least this fast, if not faster:
Most JavaScript engines use a dictionary-like data structure as
storage for object properties - each property access requires a
dynamic lookup to resolve the property's location in memory. This
approach makes accessing properties in JavaScript typically much
slower than accessing instance variables in programming languages like
Java and Smalltalk. In these languages, instance variables are located
at fixed offsets determined by the compiler due to the fixed object
layout defined by the object's class. Access is simply a matter of a
memory load or store, often requiring only a single instruction.
To reduce the time required to access JavaScript properties, V8 does
not use dynamic lookup to access properties. Instead, V8 dynamically
creates hidden classes behind the scenes. [...] In V8, an object changes
its hidden class when a new property is added.
It sounds like adding a new key might be slightly slower, though, due to the hidden class creation.
Yes, you can assume that adding a key, and later using it for access are effectively constant time operations.
Under the hood the JS engine may apply some techniques to optimize subsequent lookups, but for the purposes of any algorithm, you can assume O(1).
Take a look at a similar question How does JavaScript VM implements Object property access? and the answer. Here I described the optimization technique used by JS engines and how it affects the key lookup performance. I hope these details help you write more efficient JS code.

Categories

Resources