An optional argument to the flush method is the number of bytes we plan to write to the drive and we can determine how large our SO is with mySO.getSize(). Flash MX allows an end user not only to specify whether or not to allow sharedobjects, but also to control the total disk space allocated to sharedobjects which by default is 100k. If at any stage you attempt to write more data than the user's system allows, the user will be presented with a prompt such as that shown in Figure 1.1. When such a prompt is triggered the flush method which caused the prompt will return the string "pending" rather than true or false. We now see that our success variable in the example above may turn out to be "pending" which could cause problems when attempting to check if our write operation was successful (via a conditional statement for instance). This will be resolved momentarily.


Figure 1.1 The Local Storage Reuqest Prompt

The new event model allows us to trigger a function when a value is returned from the flush method. The function defined via SharedObject.onStatus is triggered after a flush operation which requests extra space is resolved. Note that this function is not triggered while a flush operation remains pending (awaiting a user's authorization to write to the disk for instance), nor is it triggered when a flush operation can be completed immediately within the existing space confines set by the user. So if my client allows 10k to be written to their disk and I attempt to write 1k, the onStatus function will not be invoked. When invoked, the function is passed an object indicating the success or failure of the operation. Macromedia's docs suggest the object contains a class property and a code property however from my tests I've found it actually includes a level property in place of the class property. A successful request for additional allocation returns an object with a level property set to the string "status" and a code property of "SharedObject.Flush.Success" while an unsuccessful request returns a level property of "error" and a code of "SharedObject.Flush.Failed". Implementing a function which checks the return value of onStatus allows us to successfully determine whether or not our write operation proceeded:

mySO = SharedObject.getLocal("test");
mySo.data.name = "Joes";
success = mySO.flush(100000);
if (success == "pending") {
 mySO.onStatus = function(result) {
  if (result.code == "SharedObject.Flush.Success") {
   trace("Sucess writing to disk");
   writeSuccess = true;
  } else {
   trace("Failure writing to disk");
   writeSuccess = false;
  }
 };
} else {
 writeSuccess = success;
}

When we add data to our SO we specify that we want it to be stored long term on the user's disk by adding it to the 'data' child. Adding information elsewhere makes it expendable. Also note that only SOs with properties in the data child will actually be written to the disk, my tests have shown a SO with an empty data child is not saved.
The following code creates a new SO, saves it, deletes it, then reloads it. The for..in loop then traces all the values it found in the reloaded version. Note that the shortLived variable, which was not part of the data child is no longer present, while the stickAround variable is. Also note that the variables preserve their data types; we don't have to convert numbers from their string saved form back into numbers as we used to with cookies.

// Create an SO
mySO = SharedObject.getLocal("test");
// Add some expendible data
mySO.shortLived = "Woe is me, the short lived variable";
// Add some important data
mySO.data.stickAround = "I'll be here for years to come!";
mySO.data.num = 123;
mySO.data.obj = new Array(4, 5, 6, 7);
// Write the SO to the disk (I'm not checking for success here)
mySO.flush();
// Delete the SO
delete mySO;
// Load the SO back in
mySO = SharedObject.getLocal("test");
// Scan the SO for values
for (a in mySO.data) {
 trace(a+": "+mySO.data[a]);
}

An interesting thing to note is that when you reload a previously written SO, change a value or two and re-write it, the original file's contents isn't exactly overwritten. Instead the new additions are merged with the old file, overwriting any previous definitions but retaining values which weren't altered. You can see it in action by trying out this code:

// Create an SO
mySO = SharedObject.getLocal("test");
// Add some important data
mySO.data.stickAround = "I'll be here for years to come!";
// Write the SO to the disk (I'm not checking for success here)
mySO.flush();
// Delete the SO
delete mySO;
// Reload the SO
mySO = SharedObject.getLocal("test");
// This time we're not adding any data, so when we write
// our SOit should the old data be overwritten, right?
mySO.flush();
// Delete the SO
delete mySO;
// Load the SO back in once more,
mySO = SharedObject.getLocal("test");
// Scan the SO for values
for (a in mySO.data) {
 trace(a+": "+mySO.data[a]);
}
// Wrong! The trace shows our old values all still exist!

Continued overleaf...