3
votes

In my outlook WebAddin, i am trying to register for mail ItemChange event using below code.

    Office.context.mailbox.addHandlerAsync(Office.EventType.ItemChanged, mailItemSelectionChanged, [], function (result) {
            if(result && result.status != 'succeeded'){
                console.error('result => ' + result);
             }
});

Whenever user changes mail in pinned mode, i receive mail change event for first time. then if there is change in conversation, i am reloading the plugin with location.reload() to clear the cache and load addin fresh.

After reload of plugin, it fails to register mailItemChange event and throwing below error :

{"code": 5001, "message": "An internal error has occurred.", "name": "Internal Error"}

It is failing in Browser and some windows machines(working in many other cases).

outlookDiagnostics :

{"host": "Outlook", "platform": "OfficeOnline", "version": "16.0.9215.1000"}

1
@Mac_Outlook_Extensibility, any update - Rajeev
This could be because you are reloading the page and trying to register for an already registered event, inside the mailItemSelectionChange method instead of reloading the page, get the new item and act upon it. Here is an example for addHandlerAsync usage dev.office.com/reference/add-ins/outlook/1.5/… - Mac_Outlook_Extensibility
@Mac_Outlook_Extensibility when i reload the page, everything should be reset right?. It is working in Mac and Windows platforms. Why it will fail in WebClient of browsers. When i reload, i am reinitializing the office context. so it shoun't be the case of reregistering - Rajeev
Once registered, event handlers stay registered for the lifetime of the opened add-in, regardless of reinitializing the office context. The intent of the ItemChanged event is to allow developers to update rather than reload the add-in entirely. - Outlook Add-ins Team - MSFT
@OutlookAdd-insTeam-MSFT is there any way to identify if the handler is already registered or not. so that i will not register again. In this case, i am not able to ideintify as i am reloading the plugin - Rajeev

1 Answers

2
votes

I could figure out the following behaviors with respect to Office.EventType.ItemChanged event registration:

  1. You can not register more than one event handlers. Most of the people are gettings error when they try to register an event handler the second time such that the first event handler was NOT unregistered.
  2. Event handler's registration lives beyond the life of the web page of your add-in. This means that when your add-in unloads the current web-page and reloads the same or a different web-page (i.e. it navigates to another web page), the registration of your event handler would still be kept.
  3. While unregistering the event handler, you not only have to provide the handler function's name but also ensure that the function is exactly the same you used to register the event with. In other words, if you try to unregister the event handler AFTER you have reloaded the web-page, the object of the handler function is not the same and hence the event handler would not get unregistered.
  4. The event handler registration is lost when Outlook closes the add-in pane.

So in your case, you need to unregister the event before calling the location.reload() as shown below.

Office.context.mailbox.removeHandlerAsync(Office.EventType.ItemChanged, {handler: mailItemSelectionChanged}, function(result) {
    if (result.status === Office.AsyncResultStatus.Failed) {
        console.log('Item Change event could not be unregistered.');
        console.log(result.error);
    }
    else {
        console.log('Item Change event unregistered successfully.');
    }
});
setTimeout(function() {location.reload();}, 100);

Those who want to navigate to the same or another web-page from their add-in, they can attach click event handlers to the anchor tags (or buttons) in order to ensure that ItemChanged event handlers have been unregistered before the current page is unloaded. I have done this using the following code:

$(document).ready(function() {
    $('.NavBarContainer a').toArray().forEach(function(anchor1, index) {
        $(anchor1).click(function(event) {
            if(itemChangeEventRegistered) {
                unregisterItemChangeHandler();
                setTimeout(function() {window.location = anchor1.href;}, 100);
                return false;
            }
            return true;
        });
    });
});