Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#4620 closed defect (invalid)

Reload Tree & ItemFileReadStore, error

Reported by: ronaldbroens@… Owned by: Jared Jurkiewicz
Priority: high Milestone: 1.0
Component: Dijit Version: 0.9
Keywords: Cc: Dustin Machi
Blocked By: Blocking:

Description (last modified by Adam Peller)

I have an application that uses an Tree widget. Because the tree can change I want to reload it. But when i completly destroy the Tree, and delete the store i get the error

'dojo.data.ItemFileReadStore?: a function was passed an item argument that was not an item'

I am using the following (test)code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Progress Bar Demo</title>
    <style type="text/css">
        @import "/libs/dojo-release-0.9.0/dijit/themes/tundra/tundra.css";
        @import "/libs/dojo-release-0.9.0/dojo/dojo.css"
    </style>
        <script type="text/javascript" src="/libs/dojo-release-0.9.0/dojo/dojo.js"
                djConfig="parseOnLoad: false"></script>
        <script type="text/javascript"> 
 
  dojo.require("dojo.data.ItemFileReadStore");
        dojo.require("dijit.Tree");
        dojo.require("dojo.parser");

        var poptarts =
                { label: 'name',
                   identifier: 'name',
                   items: [
                     { name:'Fruit', type:'category'},
                     { name:'Cinammon', type: 'category'},
                     { name:'Chocolate', type: 'category'}
                    ]
                };
                               
                               
                var mytree = null;
                var popStore = null;   
               
                function init()
                {
                        loadTree();
                }
               
                dojo.addOnLoad(init);
               
                function reload()
                {
                        mytree.destroy();
                        alert('Tree destroyed...');               
                        delete popStore;                       
                        loadTree();
                }
               
                function loadTree()
                {
                        /*<div dojoType="dijit.Tree" store="popStore" labelAttr="name"></div>*/
                        popStore = new dojo.data.ItemFileReadStore({data: poptarts});
                        mytree = new dijit.Tree(
                                {store : popStore, labelAttr : name, id : 'mytreewidget'},
                                document.createElement('div')
                        );                 
                        dojo.byId('myTreeBox').appendChild(mytree.domNode);
                }
       
</script>
</head>
<body class="tundra">
                <a href="javascript:reload()">Reload</a>
        <div id="myTreeBox"></div>
</body>
</html>

Change History (14)

comment:1 Changed 12 years ago by Adam Peller

Cc: Dustin Machi added
Milestone: 1.0
Owner: set to Jared Jurkiewicz

Hi Jared. Is this a data problem or a tree problem?

The error message might read better if we strike the first "item"

comment:2 Changed 12 years ago by Jared Jurkiewicz

Technically, usage error for ItemReadFileStore?. dojo.data.ItemFileReadStore? reuses the object passed in to construct the items list. So, they're modified/updated when they're passed in. So, they can't keep reusing the same object all the time like that. What they'd need to do is generate a new object to pass in when they load that store.

The only other alternative (which would be horribly slow), is for the store to clone the object. Not sure that's a good solution, either.

Though, it's not likely people would pass in a huge object here.

comment:3 Changed 12 years ago by Jared Jurkiewicz

And I just tried using this testcase and I can't reproduce the problem with it.

Do we have any contact information so I can get better info on what they're doing? This isn't failing for me.

comment:4 Changed 12 years ago by Adam Peller

just what's here. reporter, if you're watching, please fill in the reporter field or otherwise include your e-mail. without info to reproduce this, we'll have to close this out. let's wait a couple of days.

comment:5 Changed 12 years ago by bill

BTW Dustin added code to Tree to respond to updates (deletes, inserts, and updates) in the store, so maybe you shouldn't be reloading the whole tree anyway.

comment:6 in reply to:  description Changed 12 years ago by guest

Hello there, i am the poster of this bug.

First of all my browser/OS spec: Windows XP SP2 Firefox 2.0.0.7 Dojo 0.9 (final)

To activate this bug you must reload the tree (click on reload), the first time this is not a problem. But if you click again it will fire the error.

And if you must know i am using tree update function, so that if something changes in the store the tree will update himself, but thee tree does not support change of parent / children of an item.

Because i can change the structure so much, the widget is no longer valid, my only option is to reload it. My current work a round is give an unique id to the tree and when reloading, create always an other id.

I reported this bug because this problem caused me an complete workday and want to help this project. Also my work a round is quick-and-dirty method and will cause memory leaks (there are still some left-overs of the old trees in the memory..)

So.. enough to get going with this bug report ??

comment:7 Changed 12 years ago by guest

Sorry i forget to post my email for contact: ronaldbroens@…

comment:8 Changed 12 years ago by Dustin Machi

Thanks for replying.

Some Notes:

  • The above test is still invalid for the reasons that jared mentioned. You cannot pass that same object to create a new which would mess up the creation of the second store since the first store will take over the original object.
  • There are some known problems with the store implementations/dojo.data in that when you delete an item from the store it deletes the items but does not delete any references to that item that exist in the store.
  • I will need to check out the change of parent case. The tree should be getting that update notification and should at least be aware that the change has taken place. We'll probably need to make it look into any modified childAttr on the item and see if it needs to make any adjustments to itself.

comment:9 Changed 12 years ago by Jared Jurkiewicz

And can you provide a working testcase that shows the problem. The supplied testcase doesn't reproduce a reloading failure (Probbaly because no modifications occur). Though I still imagine that the reloading failure is caused by reusing the same object, which you can't do as the store takes and modifies those exact JS objects. If you want to reload with clean data, you must create clean data for it.

You should do something like:

dojo.data.ItemFileReadStore?({data: dojo.fromJson(dojo.toJson(poptarts))}); And clone the data object before handing it to the store each time.

comment:10 Changed 12 years ago by Adam Peller

Description: modified (diff)
Reporter: changed from guest to ronaldbroens@…
Resolution: invalid
Status: newclosed

Please reopen if you can provide a case which meets these requirements and please use attach file.

comment:11 Changed 12 years ago by guest

Resolution: invalid
Status: closedreopened

My testcode WILL generate an error if you do the following (just use the code as it is, just change the paths to the dojo files)

Testcase: -Browser:

Will produce an eror on Ie7 & Firefox 2.0.0.7 OS: Windows XP SP2

-Dojo version: 0.9 Final

To do to reproduce: -Load the test page, make sure that your dojo paths are correct and the page loads -You will see an tree -Click on 'reload' -Tree WILL RELOAD, No problem there! (Yet)

--MY TEST CASE DOES NOT END HERE--

-Click on 'reload' again!

-Now i get an error: 'dojo.data.ItemFileReadStore??: a function was passed an item argument that was not an item' -My Tree Will NOT BE SHOWN -Dojo is broken form that point, reload button will not build an tree any more!

comment:12 Changed 12 years ago by Jared Jurkiewicz

Resolution: invalid
Status: reopenedclosed

Finally reproduced on another machine. Problem is usage error of the store. It is the exact thing I pointed out earlier that I believed was likely the cause of the issue you were seeing. Repeating my previous statement below:

Technically, usage error for ItemReadFileStore??. dojo.data.ItemFileReadStore?? reuses the object passed in to construct the items list. So, they're modified/updated when they're passed in. So, they can't keep reusing the same object all the time like that. What they'd need to do is generate a new object to pass in when they load that store.

The problem is that you keep reusing the exact same data objects over and over. The store has modified them as part of absorbing them and indexing them, assigning identities to them, adding a back reference to the store, etc. So passing them back in, after they have been modified, eventually causes an issue. This can be very easily handled in your own code by always passing a copy of the data. I've also already shown a way to do that. Change your code to do:

dojo.data.ItemFileReadStore??({data: dojo.fromJson(dojo.toJson(poptarts))}); Clone the data before passing it in so the master copy is untouched.

The ItemFileReadStore? design uses the objects passed in directly on purpose, it was more efficient than cloning everything (Although it could and would just use the exact same code I noted above, the pairing toJson, fromJson). If you need to keep reusing the same dataset, then you need to make sure to clone it before you pass it in to ItemFileReadStore?. Once you make that one line change in your code, the problem should go away.

Your testcase, modified: <!DOCTYPE HTML PUBLIC "-W3CDTD HTML 4.01EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html> <head> <title>Progress Bar Demo</title>

<style type="text/css">

@import "dijit/themes/tundra/tundra.css"; @import "dojo/dojo.css"

</style>

<script type="text/javascript" src="dojo/dojo.js"

djConfig="parseOnLoad: false"></script>

<script type="text/javascript">

dojo.require("dojo.data.ItemFileReadStore?");

dojo.require("dijit.Tree"); dojo.require("dojo.parser");

var poptarts =

{ label: 'name',

identifier: 'name', items: [

{ name:'Fruit', type:'category'}, { name:'Cinammon', type: 'category'}, { name:'Chocolate', type: 'category'}

]

};

var mytree = null; var popStore = null;

function init() {

loadTree();

}

dojo.addOnLoad(init);

function reload() {

mytree.destroy(); alert('Tree destroyed...'); delete popStore; loadTree();

}

function loadTree() {

var popStore = new dojo.data.ItemFileReadStore?({data: dojo.fromJson(dojo.toJson(poptarts))}); mytree = new dijit.Tree(

{store : popStore, labelAttr : name, id : 'mytreewidget'}, document.createElement('div')

); dojo.byId('myTreeBox').appendChild(mytree.domNode);

}

</script> </head> <body class="tundra">

<a href="javascript:reload()">Reload</a>

<div id="myTreeBox"></div>

</body> </html>

comment:13 Changed 12 years ago by guest

Ok i get it now, dojo store change my original object(s) so i can not used it again.

One question remaining: I made this simple example for this bugreport, in my real application am using an url where the store must gets its data, why do i also get this message when not decalaring an localobject but using an url for the store?

This report can be keep closed now. My work-a-round works, by giving an unique id to the tree, but in my opinion is still ugly coding(Not this example, using an url in the store).

comment:14 Changed 12 years ago by guest

Sorry my mistake,

Retesting with url is NOT a problem, You can ignore my previous message.

I will check my code again to check if there are not any global data string or object hanging around some where!

Thanks for all the help here!

Note: See TracTickets for help on using tickets.