PowerPoint Add-in only works after the third initialization on Office Online

147 Views Asked by At

Context


In my company, I am in charge of developing an Add-in of type Content App only for PowerPoint. The add-in is built with ASP.NET MVC (4.5) and AngularJS (1.6.8) and works seamlessly on PowerPoint client (Version 1811, Build 11029.20079).

Tests procedure
Windows 10 64-bits
Chrome, v70.0.3538.110 (Official Build) (64-bit)
Adblocker disabled

Manifest used
This manifest passed the validation tool (https://www.npmjs.com/package/office-addin-validator).

<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:type="ContentApp">
  <Id>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</Id>
  <Version>1.0.0.0</Version>
  <ProviderName>My Company</ProviderName>
  <DefaultLocale>en-US</DefaultLocale>
  <DisplayName DefaultValue="Office Add-in name" />
  <Description DefaultValue="Office Add-in description." />
  <IconUrl DefaultValue="https://my-company.com/PluginLogo32.png" />
  <HighResolutionIconUrl DefaultValue="https://my-company.com/PluginLogo64.png" />
  <SupportUrl DefaultValue="https://my-company.com/support/" />
  <AppDomains>
    <AppDomain>my-company.com</AppDomain>
  </AppDomains>
  <Hosts>
    <Host Name="Presentation" />
  </Hosts>
  <Requirements>
    <Sets DefaultMinVersion="1.1">
      <Set Name="Settings" />
    </Sets>
    <Methods>
      <Method Name="Settings.get" />
      <Method Name="Settings.set" />
      <Method Name="Settings.remove" />
      <Method Name="Settings.saveAsync" />
    </Methods>
  </Requirements>
  <DefaultSettings>
    <SourceLocation DefaultValue="https://my-company.com/plugin" />
    <RequestedWidth>800</RequestedWidth>
    <RequestedHeight>600</RequestedHeight>
  </DefaultSettings>
  <Permissions>ReadWriteDocument</Permissions>
  <AllowSnapshot>true</AllowSnapshot>
</OfficeApp>

Office initialization used

<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<script type="text/javascript">

    var init = function () {
        App.tags = @Html.Raw(WorkContext.ActivPortalUserEntity.GetUserTagsAsJson());
        App.languages = @Html.Raw(LocalizationManager.GetPortalJsonScript());
        App.AP_URL = '@WorkContext.Uri';
        App.V_KEY_FORM = '@AntiforgeryHelper.GetTokenName()';
        App.V_VALUE_FORM = '@AntiforgeryHelper.GetToken()';
        App.LabelURLSuffix = '';
        App.URLSuffix = '@Model.TemplateDocument.URLSuffix';
        App.IsDefaultUser = @Json.Encode(WorkContext.ActivPortalUserEntity.IsDefaultUser);
        App.DashboardParametersQueryString = '@Html.Raw(Model.RenderContext.Request.GetParametersAsQuerystring())';
        App.DashboardFilters = @Html.Raw(@JsonConvert.SerializeObject(Model.RenderContext.Request.GlobalCriteriaObjects));
        App.ZoomFilters = @Html.Raw(@JsonConvert.SerializeObject(Model.RenderContext.Request.GlobalCriteriaIndexes));
        App.WebPartFormatUseCorner = true;
        App.DeportedToggleView = true;
        App.ToggleViewMode = 'accordion';
        App.searchPlaceHolderText = "@Resource("L_appSearchPlaceHolder_Text", "Portal")";
        App.viewType = '';
        App.documentRepository = '@ApplicationConfigService.ActivPortalServerConfig.DocumentsRepository';
        App.WPAllowIconsHide = false;
        App.Language = '@WorkContext.UserLanguage';
        App.searchURL = [];
        App.EditMode = false;
        App.EditContentMode = false;
        App.CATALOG_PROXY = '@WorkContext.Uri' + 'Portal/CatalogProvider';
        App.RENDER_URL = '@WorkContext.Uri' + 'Portal/Render';
        App.CHOICE_PROXY = '@WorkContext.Uri' + 'Portal/Render/TemplateRequest';
        App.POST_TEMPLATE_PROXY = '@WorkContext.Uri' + 'Portal/Render/TemplateRequest';
        App.moduleScripts = @Html.Raw(JsonConvert.SerializeObject(Model.GetPageScripts()));
        App.moduleStylesSheets = @Html.Raw(@JsonConvert.SerializeObject(Model.GetPageStyles()));
        App.angularClientContext = @Html.Raw(@Html.GetJsonClientContext());

        App.scriptDebug = (typeof App.scriptDebug == undefined) ? false : App.scriptDebug;
        App.ScriptsManager = new Activportal.UI.Resources({ scriptDebug: App.scriptDebug });
        App.StylesManager = new Activportal.UI.Resources();

        //Localization
        MinimizeTip_Text = "@Resource("L_Minimize_Text", "Portal")";
        ExpandTip_Text = "@Resource("L_Maximize_Text", "Portal")";
        ErrorUpdatingPart_Text = "@Resource("L_InvalidURL_Text", "Portal")";
        ConfirmRemoveGlobalFilter_Text = "@Resource("L_ConfirmRemoveGlobalFilter_Text", "Portal")";
        WaitMessage_Text = "@Resource("L_WaitMessage_Text", "Portal")";
        SessionEnd_Text = "@Resource("L_SessionEndMessage_Text", "Portal")";

        window.addEvent('domready', function () {
            App.isDashboardLoaded();
            App.Start();
        });
    };

    try {
        if (Office) {
            Office.initialize = init;
        }
        else {
            console.log("Office.js is missing.");
            if (!window.external.GetContext) {
                init();
            }
        }
    } catch (e) {
        console.log(e);
    }
</script>

Problem


Just to repeat myself, The Add-in works seamlessly on PowerPoint 2016 client (see above for version). However, in PowerPoint Online I struggle on an issue: the initialization of the add-in.

  1. When inserting the Add-in or reloading the login page is displayed with an opacity as follow: Add-in initialization

  2. Then after 2 seconds this message appears: "Sorry...We could not start the Add-in because we encountered a problem. Try later or contact your system administrator." Add-in initialization error message
    The only message I get from the console are the followings: enter image description here

  3. At this point, i count 1 initialization. When I click on “DÉMARRER” the same thing happens (second init). And then, when I click again (third init). The Add-in finally works like on PowerPoint client. Here is what is look like when the login page works. https://imgur.com/F9QNvvg

So, on Office Online, it’s only the third initialization, the Add-in it works. I noticed approximately the same behavior for all major browser in their last version.

Question


Is there something I am missing?
I am open to any suggestions, I didn't find any solution on this particular matter.

1

There are 1 best solutions below

0
On

What I did to fix this issue
Well, my mistake has been to not understand well how Office.js works.

In my login page
- I added the script Office.js.
- I initialize the script.

if (Office) {
   if (Office.context === undefined) {
      Office.onReady(function () { });
   }
}

In my main page
- I change the way to initialize the script.

if (Office) {
   if (Office.context === undefined) {
      Office.onReady(function () { });
   }
}

Conclusion
It seems Office.js must be present in the first page of the application. And in every pages which use Office API.

In addition, It is better to Use Office.onReady() instead of Office.initialize().

Things to note:

  • I had to contact Microsoft to found out this solution.
    Documentation not that abvious, perhaps?
  • I still have some error in console but i can use the Add-in and the API without problem.