Office-js: [Outlook] Office.mailbox.item.body.getAsync provides out-of-date information (new OWA)

Created on 9 Feb 2019  路  5Comments  路  Source: OfficeDev/office-js

In the new version of Outlook Web App (the one shown by turning on the Try the new Outlook toggle), calling Office.mailbox.item.body.getAsync when in compose-mode does not always return the mail body currently displayed on the page. It instead returns the mail body from the last-saved version of the draft from the server, which is often not current.

Expected Behavior


When in compose-mode, I would expect that calling Office.mailbox.item.body.getAsync would return the text that I can currently see on the page. This is the behavior of body.getAsync in the old version of OWA (tested on version 16.0.10205.10000), as well as the behavior of Office.mailbox.item.subject.getAsync in both the old and new versions of OWA.

Current Behavior



When in compose-mode, Office.mailbox.item.body.getAsync frequently returns text that is not up-to-date with what the user has typed in the mail body. After making a change to the body by typing in the contenteditable div on the page, body.getAsync will continue to return the text from before the change for 30 seconds to several minutes after the change was made. When body.getAsync finally does return the most up-to-date results, it appears to coincide with the draft being saved to the server. This seems to indicate that body.getAsync is returning the version of the body stored on the server, not the version of the body that is being displayed to the user. This is the case both when retrieving the body as HTML or as plain text.

Steps to Reproduce, or Live Example




Unfortunately I cannot share the live example from the project where we are experiencing this issue, since it is a closed-source product, but the repro is fairly simple:

  1. Add the following script to a task pane which runs in a compose-mode email message:
const pollMailBody = setInterval(() => {
    Office.mailbox.item.body.getAsync(Office.CoercionType.Text, (result) => {
        if (result.status === Office.AsyncResultStatus.Succeeded) {
            console.log(result.value);
        }
    });
}, 1000);

Office.initialize = pollMailBody;
  1. Open a new compose mail, and open the task pane. Console logs of a blank string (the blank contents of the mail body) should start appearing once per second.
  2. Type in the message body. Notice that the console logs won't immediately reflect the changes made to the message body. Sometimes they'll become up-to-date in a few seconds, other times it takes 30 seconds to several minutes.

Context



Our plugin needs to know the current contents of the mail body and subject line at all times, so it can update various pieces of UI in response to changes the user has made to the mail. Because there is currently no way to subscribe to changes to the mail body, we poll for changes by calling body.getAsync on a regular interval. This more or less works as expected in Windows Outlook 2013/2016, Mac Outlook, and the old version of OWA. However, the massive delay in new OWA between when a user changes the body and when body.getAsync reflects those changes makes it impossible for the plugin to operate as designed.

Your Environment

  • Platform [PC desktop, Mac, iOS, Office Online]: Office Online
  • Host [Excel, Word, PowerPoint, etc.]: Outlook
  • Office version number: 16.0.10908.10000
  • Operating System: MacOS High Sierra, Windows 10
  • Browser (if using Office Online): Chrome, Firefox

Useful logs

Outlook fixed product bug

Most helpful comment

@exextoc, we did some more investigation into this bug because it is fairly blocking for the functionality of our add-in. Here's what we discovered:

  • Calling saveAsync on the mail item does not cause body.getAsync to return the correct value, so this is not a viable workaround.
  • Calling body.prependAsync with an empty string DOES cause body.getAsync to return the correct value. However, it also adds an item to the undo stack, so this workaround won't work for our purposes.
  • If the user blurs the mail body by clicking elsewhere into the page, body.getAsync will immediately return the correct value.

We did a little digging into OWA's minified source code to see if we could figure out where the bug might be happening, and we were actually able to fix the issue with a two-line change to https://ow2.res.office365.com/owamail/2019031102.10/scripts/owa.Addins.mail.js

When the file is pretty-printed, lines 37124-37161 look like this:

var ce = n(169)
          , le = n(1576)
          , ue = n(1)
          , de = Object(ue.mutatorAction)("appendOnSend", function(e, t) {
            var n = e.appendOnSend;
            if (n) {
                for (var r = !1, a = 0; a < n.length; a++)
                    if (n[a].id === t.id) {
                        e.appendOnSend[a] = t,
                        r = !0;
                        break
                    }
                r || e.appendOnSend.push(t)
            }
        })
          , pe = function(e) {
            return function() {
                return e.content
            }
        }
          , fe = function(e) {
            return function(t, n) {
                (Object(le.a)(e, t),
                "HTML" == e.bodyType) && Object(l.b)(e).addinPlugin.updateContent(t, n)
            }
        }
          , me = function(e) {
            return function() {
                return e.bodyType
            }
        }
          , he = function(e) {
            return function(t) {
                var n = Object(l.b)(e).addinPlugin;
                n.prependContent(t),
                Object(le.a)(e, n.getContent())
            }
        }

Lines 37139-37142 are called when the add-in calls body.getAsync:

, pe = function(e) {
            return function() {
                return e.content
            }

The bug no longer repros if this code is changed to:

, pe = function(e) {
            return function() {
                return Object(l.b)(e).addinPlugin.getContent()
            }

It's pretty difficult to follow the flow of the code when the variable names are minified, but it appears that e.content is not always updated in real-time as the user types in the mail body, whereas getting the addinPlugin editor instance and calling .getContent() on it does get the most up-to-date content.

We were only able to test this in Chrome, and we don't have the context to understand the downstream effects of this change since the minified code is hard to follow, but it seems like there's a possibility that this fix might be relatively straightforward? We're at a loss for how to achieve the desired functionality of our plugin with the current behavior of body.getAsync, so we'd love to help in any way we can to get this issue resolved!

All 5 comments

Thanks for reporting this. It has been put on our backlog. We unfortunately have no timelines to share at this point.

Thanks, @exextoc.
Is there a workaround? If we don't get identical behaviour cross-platform, then we can't rely on it.

@exextoc, we did some more investigation into this bug because it is fairly blocking for the functionality of our add-in. Here's what we discovered:

  • Calling saveAsync on the mail item does not cause body.getAsync to return the correct value, so this is not a viable workaround.
  • Calling body.prependAsync with an empty string DOES cause body.getAsync to return the correct value. However, it also adds an item to the undo stack, so this workaround won't work for our purposes.
  • If the user blurs the mail body by clicking elsewhere into the page, body.getAsync will immediately return the correct value.

We did a little digging into OWA's minified source code to see if we could figure out where the bug might be happening, and we were actually able to fix the issue with a two-line change to https://ow2.res.office365.com/owamail/2019031102.10/scripts/owa.Addins.mail.js

When the file is pretty-printed, lines 37124-37161 look like this:

var ce = n(169)
          , le = n(1576)
          , ue = n(1)
          , de = Object(ue.mutatorAction)("appendOnSend", function(e, t) {
            var n = e.appendOnSend;
            if (n) {
                for (var r = !1, a = 0; a < n.length; a++)
                    if (n[a].id === t.id) {
                        e.appendOnSend[a] = t,
                        r = !0;
                        break
                    }
                r || e.appendOnSend.push(t)
            }
        })
          , pe = function(e) {
            return function() {
                return e.content
            }
        }
          , fe = function(e) {
            return function(t, n) {
                (Object(le.a)(e, t),
                "HTML" == e.bodyType) && Object(l.b)(e).addinPlugin.updateContent(t, n)
            }
        }
          , me = function(e) {
            return function() {
                return e.bodyType
            }
        }
          , he = function(e) {
            return function(t) {
                var n = Object(l.b)(e).addinPlugin;
                n.prependContent(t),
                Object(le.a)(e, n.getContent())
            }
        }

Lines 37139-37142 are called when the add-in calls body.getAsync:

, pe = function(e) {
            return function() {
                return e.content
            }

The bug no longer repros if this code is changed to:

, pe = function(e) {
            return function() {
                return Object(l.b)(e).addinPlugin.getContent()
            }

It's pretty difficult to follow the flow of the code when the variable names are minified, but it appears that e.content is not always updated in real-time as the user types in the mail body, whereas getting the addinPlugin editor instance and calling .getContent() on it does get the most up-to-date content.

We were only able to test this in Chrome, and we don't have the context to understand the downstream effects of this change since the minified code is hard to follow, but it seems like there's a possibility that this fix might be relatively straightforward? We're at a loss for how to achieve the desired functionality of our plugin with the current behavior of body.getAsync, so we'd love to help in any way we can to get this issue resolved!

We have fixed this issue and it is available in production.

In the latest version , the inline attachments are being fetched even after remove from the mail body.

Was this page helpful?
0 / 5 - 0 ratings