#7356 closed defect (fixed)
JsonRestStore prototypes on lazy objects
Reported by: | maulin | Owned by: | Jared Jurkiewicz |
---|---|---|---|
Priority: | high | Milestone: | 1.2 |
Component: | DojoX Data | Version: | 1.1.1 |
Keywords: | JsonRestStore | Cc: | [email protected]… |
Blocked By: | Blocking: |
Description
Not sure if this is a bug or by intention, but it certainly is a bug for me:
If you have a simple self-referencing JSON, then prototypes work perfectly.
If you have a JSON is loaded first, then a second JSON refers to objects in the first JSON, then protoypes work.
But if you have a JSON that refers to an as yet unloaded entity (which I imaigine is the whole point of lazy $ref'erences) then it first loads the lazy reference into the index. This means that when the item is lazy loaded, the instance is already found in the index (which is a good thing), but the protoype is never applied. So I guess prototypes are not being applied to lazy references in json.ref. The worst part of this is that if I then load the lazy item in its own store, or in any other way, it still does not get the prototype (since json.ref always finds it in its index, and it was initially instantiated without the prototype)
A test case (uses some of my own scaffolding, but you get the idea)
(function() {
var mockItemsService = new medryx.data.mock.MockRestService?(dojo.moduleUrl("medryx.data.tests", "items.json")); var mockRelatedService = new medryx.data.mock.MockRestService?(dojo.moduleUrl("medryx.data.tests", "related.json")); var scaffold = {
setUp:function() {
this.itemsStore = new dojox.data.JsonRestStore?({
service: mockItemsService, target:"/item", schema:{
prototype:{
getFoo:function() {
return this.foo;
}
}
}
});
this.relatedStore = new dojox.data.JsonRestStore?({
service: mockRelatedService, target:"/relative", schema:{
prototype:{
getBar:function() {
return this.bar;
}
}
}
});
}
}
doh.register("LazyPrototypeTests?", [
new doh.AsyncTestCase?("testProtoExistsOnRelatedLazy", function() {
relatedStore.fetch({onComplete:callback})
}, function(items) {
assertTrue(dojo.isFunction(items[0].getBar)); assertTrue(dojo.isFunction(items[0].getBar().getFoo)); FAILS
}, scaffold),
]);
})();
where the data is:
items.json:
[
{
id:"1", foo:"foo", bar:{$ref:"2"}
}, {
id:"2", foo:"foo2", bar:{$ref:"3"}
}, {
id:"3", foo:"foo3", bar:{$ref:"1"}
}
]
related.json:
[
{
id:"1", foo:"foo-rel", bar:{$ref:"/item/2"}
}, {
id:"2", foo:"foo2-rel", bar:{$ref:"/item/3"}
}, {
id:"3", foo:"foo3-rel", bar:{$ref:"/item/1"}
}
]
Attachments (1)
Change History (4)
Changed 12 years ago by
Attachment: | ref.js.patch added |
---|
comment:1 Changed 12 years ago by
comment:3 Changed 12 years ago by
Maulin, thanks for the bug report and patch, great work. I patched it a little differently, calling walk with the lazy object instead of the creating findProto function. This should actually be more correct for lazy objects as well (as they may include properties they need processing, like other lazy properties). Let me know (reopen the ticket) if this doesn't fix your problem.
I have attached a patch to ref that fixes this. basically i extracted your proto code to a local utility function and then invoke it in two places -- once where it originally was, and again near line 110 where you were adding the straight json val (property value) of "it" to the index, to be sure the prototype is created first.
This fixes the above, as well as allows arrays with lazy references to use protoypes without any problems.