Why Outlook's RoamingSettings object initializ

2019-01-24 17:45发布

问题:

Precondition:

  • Simple Outlook add-in with one (reload case) or two HTML pages (redirect case).
  • Office.initialize called before any objects access
  • Use RoamingSettings object as per documentation: How to save settings in the user's mailbox for Outlook add-ins as roaming settings

Coding:

// The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
    $(document).ready(function () {
        app.initialize();

         var settings = Office.context.roamingSettings;

        // Get the current value of the 'myKey' setting
        // let's assume it was set and stored with value "Hello World!" previously
        var value = settings.get('myKey');

        // Update the value of the 'myKey' setting
        settings.set('myKey', 'Reload World!');

        // Persist the change
        settings.saveAsync();

        var $btn_reload = $('#btnReload');
        $btn_reload.off('click').on('click', reloadThePage);
    });
};
function reloadThePage() {
    // re-load current page
    window.location.href = self.location.href;
};

Workflow:

Trough the code we are interested in value variable. First time load we assume the "value" is set to "Hello World!". After load of the page the value will be set to "Reload World!" and will be preserved to the server mailbox. After click on the HTML button will trigger simple page reload. The code will start executing entire sequence again. Per documentation after Office.initialize our "roamingSettings" object is ready to use and we check the "value" again. I am expecting this value to be "reload World!", but instead I have the old value "Hello World!".

The same situation happen when the code would navigate to yet another page. This page will be similar and after Office.initialize "roamingSettings" will still hold old value "Helllo World!" instead of saved new value "Reload World!".

Please note, the value which we store to the server with "saveAsync" was really changed. This easy to verify. Run the same scenario and after close add-in (add-in iframe) and re-open it again. The "value" on initial load of the page will be correct one "Reload World!".

Conclusion (my speculation on the issue):

When debugging the issue, I noticed Office.context.roamingSettings holds two different private objects: one called "settings..." and second "rawSettings...". On initial load "rawSetting..." will hold all the setting and the "Settings..." will not be there. After first access to particular settings key, "Settings..." object created and "RawSettings..." will be set to null. When work with settings you actually work with "Settings...". After re-load / redirect "RawSettings..." appear again, but it will hold old data, which were not updated. In same time if you close add-in completely and open it again, "rawSettings..." will hold new, updated data.

This make me think that iFrame of the add-in holds the same data somewhere, which is used to re-initialize the "in-memory" object on load. During add-in start up this data will be pulled from the mailbox, but when you reload page or redirect to another page of the app data from iFrame will be used and it is not up to date.

Would somebody clarify if this is how it's designed? Am I use the object incorrectly?

Please note, this will not be the issue for add-ins that use single page app and don't need any page re-load. This is the case when by some reason add-in needs to re-load entire page (for example to re-initialize everything from scratch) or use multiple pages application.

回答1:

This is a known issue, and is in the backlog. We don't have an ETA to share at this time.



回答2:

I've created a workaround for this issue. Here is a link to my blog post about it:

http://metrosharesolutions.com/blogs/office365development/roaming-settings-workaround/

Here is a link to my code:

https://github.com/joeparzel/RoamingFix

This workaround will somewhat disable the Custom Properties functionality but it solves the issue for those who are creating one-pagers. Here is an excerpt from the blog post:

In order to accomplish this workaround, we’ve added some extra (parsable) information to the Value that is saved with the Key – specifically we add a GUID and a date/time stamp. After appending this extra information to the value, we save the value to both Roaming Settings and Custom Properties. This is done because of the “reload” issue described in the Stack Overflow post referenced earlier. Finally, we don’t really remove values from the Roaming Settings / Custom Properties databases; rather we set the values to what our code thinks means “deleted.” To retrieve the correct value, the code will decipher which value (between Roaming Settings and Custom Properties) is correct based on the date/time stamp and return the GUID if the key has been deleted.

The code for this workaround is under the MIT license, so feel free to download and add it to your own production Outlook Add-in… after testing of course!



回答3:

As per the documentation, the saved value can be retrieved on the next time the plugin is used, isn't there anyway to reload the plugin whenever we need to retrieve the value directly after saving. This can be an acceptable workaround I guess.