ExtJS State Management bug – (patch enclosed)

The ExtJS statemanager is broken, at least in version 2.1. Do not use it. The problem is that all components save their state even if stateful is set to false… which causes some interesting issues.

By default ExtJS uses the Component Id as the state key when saving and restoring state. The issue here is that you cannot guarantee the Component Ids will be the same on any 2 Ext interface loads. For instance, a user may login open Window #1, resizes it and then logout. Everything else being equal, the user logs in and opens Window #2… oops… window #2 is going to have the componentId that Window #1 had when the state was first saved. Window #1’s state will be restored into Window #2!!

Now, what is really bad is that occasionally the Viewport componentId will collide with some other component and upon page load all you will see is a blank Ext baby blue screen. That’s because some window’s state was applied to the Viewport and Ext moved the body tag to some pixel offset off the page!

And finally, a reason why CookieProvider should not be used. Firstly, component states are stored in individual cookies and browsers generally have a limit of 50 – 100 cookies. And secondly, Apache, by default only allows 8190 bytes (characters). This includes your cookie data and your GET parameters and all other headers. If you go beyond this amount Apache, will give a 400 Bad Request error. Now, Tomcat is a little different (What I am running). Tomcat just returns a 200 OK response and ends there. No data. What seems strange is that if your header length is hovering near the 8100 mark you will get intermittent failures as your GET query string randomly pushes it over the limit. This was causing some pretty big headaches over here as our AJAX requests seemed to randomly fail.

I haven’t tried it, but you can give Saki’s HttpProvder a shot to fix the cookie length header problem. However, until there is a patch for state management, don’t use it.

[edit]

I wanted to note that Tof suggested setting Ext.Component.prototype.stateful to false.  This will prevent components from restoring the wrong state if you give all your components meaningful ids.  I talk a little about this in my post on the ExtJS Forums.  The problem is that even if you set stateful to false, components still save their state.  If you have a large app like we do at ControlPath, with a lot of users, this state pollution can be massive.  However, if you have a small app and you use the HttpProvider, Tof’s suggestion will work fine for you until a patch is released.

If you combine what Tof suggests with the following code, StateManagement will be fixed (I think… untested):

I honestly think stateful should be gotten rid of in favor of just stateId. When you set stateId, “stateful” should be activated. This breaks existing code, so the Ext folk won’t do it.

5 comments

  1. Hi,

    I’m using State Management (with my own http-provider-like), I’ve got no problem.

    But you have to :

    1) remove stateful mode on all components by default

    Ext.override(Ext.Component,{ stateful:false });

    2) give to each component you wanna keep state :

    * A unique and “meaningful” ID
    * stateful = true
    * a stateEvents {}
    * and a getState function

    So you keep control on which components can take place in the state management :)

    Cookies are not a good solution, for sure.
    Using window.name to store it would be an option :)

  2. Yeah that was my first idea too… Unfortunately setting stateful to false doesn’t keep components from saving state. Setting stateful to false only keeps components from restoring state. This is still unacceptable as you get state pollution.

    Depending on your application this may work well for some. But we have A LOT of components and a lot of users. The state pollution is massive. Even if we used the HttpProvider, the pollution would be too great.

  3. Hi TOf

    Could you guide me thru (even a code snippet) the state management ?

    I am actually trying to put together a provider for state management on a central DB. My problem might be complicated as I use viewport as well as several dynamically added panels in one of the regions of the viewport ?

    Can I enable the entire viewport as a whole for statemanagement ? This way, perhaps one can avoid individual component management.

    Please guide me as state management is very critical to my project.

    Regards

  4. Right now in Ext if you have a state provider, states are enabled by default. Take a look at the API docs to see how to setup a state provider: http://extjs.com/deploy/dev/docs/?class=Ext.state.CookieProvider

    You should not need to write a new state provider unless you find that Saki’s HttpProvider, which I mentioned in my post, doesn’t work for you. Here is the link again: http://extjs.com/forum/showthread.php?t=24970

    However, if you read my post I highly recommend that you use my patch . Especially so if you are creating dynamic panels. You really do need to set stateId for each panel you want to be stateful. Otherwise, with dynamic panels, you can never guarantee that the state that is restored will be the correct state.

Leave a Reply to Eon Pul Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">