My client-side code gets a JSON 'object' from the server, and then parses it. The parsed object contains a 'type' property, which should control the class of the object.
$.getJSON("foo.json").done(function(data, textStatus, xhr) {
$.each(data.objects, function(key, val)
{
if (val.type = "A") // make val into an object of class A, somehow?
...
else if (val.type = "B") // make val into an object of class B somehow?
... etc...
}
}
How can I create a JavaScript object of the correct type without explicitly copying over each property , or - alternatively - convert the parsed object to a different type?
I've read a little about __proto__
but get the feeling that it's a big sledgehammer for what should be a small nut...
I've seen similar questions regarding Java and Jackson, but nothing for Javascript...
My client-side code gets a JSON 'object' from the server, and then parses it. The parsed object contains a 'type' property, which should control the class of the object.
$.getJSON("foo.json").done(function(data, textStatus, xhr) {
$.each(data.objects, function(key, val)
{
if (val.type = "A") // make val into an object of class A, somehow?
...
else if (val.type = "B") // make val into an object of class B somehow?
... etc...
}
}
How can I create a JavaScript object of the correct type without explicitly copying over each property , or - alternatively - convert the parsed object to a different type?
I've read a little about __proto__
but get the feeling that it's a big sledgehammer for what should be a small nut...
I've seen similar questions regarding Java and Jackson, but nothing for Javascript...
Share asked Jul 6, 2014 at 11:45 RoddyRoddy 68.2k45 gold badges171 silver badges281 bronze badges2 Answers
Reset to default 5you could do something like this
function ObjectFactory() {
this.newInstance = function(val) {
if (val.type == "A") return new A(val);
if (val.type == "B") return new B(val);
}
}
function A(data) {
// do something with the data
this.property = data.property;
}
function B(data) {
// do something with the data
this.property = data.property;
this.bSpecificProperty = data.bSpecificProperty;
}
$.getJSON("foo.json").done(function(data, textStatus, xhr) {
var objectFactory = new ObjectFactory();
var objects = $.map(data.objects, objectFactory.newInstance);
console.log(objects);
}
if you gave a better example of what the right type was, and some sample data i could provide a better answer.
You haven't specified what - if any - pattern you are implementing but as another answer has alluded to, you will have to adopt some kind of convention during an object's construction. You don't necessarily have to explicitly account for each type though... and you could also be a little lazy merging your JSON data with $.extend
if you are satisfied with it's integrity?
I'd also include a helper function for resolving "types" within a given scope - it's a mon practice to namespace objects in a project to avoid polluting the global scope. For example:
function namespace(str, scope){
scope = scope || window;
var parts = str.split('.');
while(parts.length)
scope = scope[parts.shift()];
return scope;
}
Foo = {};
Foo.Bar = function(conf){
// some kind of constructor
$.extend(this, conf);
};
// test...
var json = {
type: 'Foo.Bar',
var1: 1,
var2: 2,
var3: 3
};
var obj = new (namespace(json.type))(json);
console.log(obj, obj instanceof Foo.Bar);
fiddle ... or to fit with your own code:
$.getJSON("foo.json").done(function(data, textStatus, xhr){
data.objects = $.map(data.objects, function(obj){
return new (namespace(obj.type))(obj);
});
});