OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
677 stars 95 forks source link

Office does not initialized in Excel Js addin #2321

Closed savanetllc closed 7 months ago

savanetllc commented 2 years ago

Message from office-js bot: We’re closing this issue because it has been inactive for a long time. We’re doing this to keep the issues list manageable and useful for everyone. If this issue is still relevant for you, please create a new issue. Thank you for your understanding and continued feedback.

I have created addin using Yeoman generator with ReactJs framework and use VS 2019 for development on Windows 10 with Office 365 (version: 2111 (Build: 14701.20262)) installed on machine. Whenever I load my addin in Debug mode (using NPM) locally as well as uploaded manifest file to Central Admin pointing to release code hosted on server), most of the time page in sidebar (taskpane) doesn't load and keeping showing progress loading animation (though sometimes it loads successfully, once out of 4 tries). We have to right click in Sidebar and refresh page multiple times then main page loads up. Following is the Render condition in App.js which keep showing Progress animation because office is not initialized

 render() {
        const { title, isOfficeInitialized } = this.props;

        if (!isOfficeInitialized) {
            return (
                <Progress
                    title={title}
                    logo={require("./../../../assets/logo-filled.png")}
                    message="Please right click and refresh the page to see app body."
                />
            );
        }

And following is "Index.js" file in taskpane folder

import "office-ui-fabric-react/dist/css/fabric.min.css";
import App from "./components/App";
import { AppContainer } from "react-hot-loader";
import { initializeIcons } from "office-ui-fabric-react/lib/Icons";
import * as React from "react";
import * as ReactDOM from "react-dom";
import './taskpane.css';
/* global document, Office, module, require */

initializeIcons();

let isOfficeInitialized = false;

const title = "Add-in";

const render = (Component) => {
  ReactDOM.render(
    <AppContainer>
      <Component title={title} isOfficeInitialized={isOfficeInitialized} />
    </AppContainer>,
    document.getElementById("container")
  );
};

/* Render application after Office initializes */
Office.initialize = () => {
  isOfficeInitialized = true;
  render(App);
};

/* Initial render showing a progress bar */
render(App);

if (module.hot) {
  module.hot.accept("./components/App", () => {
    const NextApp = require("./components/App").default;
    render(NextApp);
  });
}

I just imported css file into this index.js file, no major changes done here. Can anyone please guide me to the right path why office is not initializing This initialization issue occurring on multiple machines even with good internet.

savanetllc commented 2 years ago

I am not sure it is related or not, but I can see following entries in Console when right click on taskpane and "Inspect"

taskpane.html:1 Tracking Prevention blocked access to storage for https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js. taskpane.html:1 Tracking Prevention blocked access to storage for https://appsforoffice.microsoft.com/fabric/1.0/fabric.min.css.

JinghuiMS commented 2 years ago

Thanks for reaching us. From your error message(Tracking Prevention blocked access to storage for), it should be cause by the bad network. Try to resolve it by adding a setTimeout(function(){},1000) to your code and write your Office specific code inside it. Feel free to leave message here if this solution doesn't work for you.

ghost commented 2 years ago

This issue has been automatically marked as stale because it is marked as needing author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. Thank you for your interest in Office Add-ins!

savanetllc commented 2 years ago

ur error message(Tracking Prevention blocked access to storage for), it should be cause by the bad network. Try to resolve it by ad

Hi @JinghuiMS, thank you for reply. I didn't get, where should I use setTimeout. I gave my Index.js file content and it has Initialize function. If I make complete "Office.initialize" function inside setTimeout, it won't trigger. So please guide me further and sorry, as I am newbie on it so might not get your point.

Office.initialize = () => { isOfficeInitialized = true; render(App); };

JinghuiMS commented 2 years ago

This solution comes from the following link, it seems you need to put all your code into setTimeout. Since it doesn't work for you, I will involve more professional people into thread to see if there're other solutions. Please expect slow response because now is a holiday season. Thanks!

JinghuiMS commented 2 years ago

@shaofengzhu Do you have any ideas on this "Tracking Prevention blocked access to storage " issue? Sorry to disturb you when you're on vacation.

savanetllc commented 2 years ago

Hi @JinghuiMS and @shaofengzhu, happy new year!! Hope you guys have good time during vacation. Is there any update on said issue (for loading Sidebar/Taskpane)?

savanetllc commented 2 years ago

@chiz-ms @JinghuiMS @dingjin-ms Please any response as have tight deadline on it.

JinghuiMS commented 2 years ago

@savanetllc Sorry for the late response~ I try to get the right contact in our side channel, and will report back.

JinghuiMS commented 2 years ago

@savanetllc sorry for the late response, we are always trying to solve your problem. First, I can't repro this issue in my side. It seems you don't call any API, it fails when you create this addin, right? If so, could your try to build one new add-in In a good network environment? Please also try to use the following 2 ways to unblock your self.

  1. use setInterval() Office.initialize = function() { setInterval(function(){ }, 1000); console.log('office is ready') }
  2. put 'MutationObserver=null;' on the top of your index.html. <!doctype html> ....
savanetllc commented 2 years ago

Hi @JinghuiMS, thank you for update. By "It seems you don't call any API, it fails when you create this addin, right?", if you mean to call my custom API then YES, I do have one API call to Server during 'App=>componentDidMount()" for checking update and then refreshing local store if update available. If you are asking something else then please explain.

Anyhow right now if I even comment out that API call from "componentDidMount()" then still face the same issue. Regarding your suggestions...

  1. This is actual root cause as "Office.initialize" method don't execute so setting interval inside it will be useless. When Office.initialize execute then add-in load successfully. For example, I have following log messages inside it which don't display in console ` Office.initialize = () => {

    console.log('office initializing');

    setInterval(function () { console.log('In SetInterval'); isOfficeInitialized = true; render(App); }, 1000);

    console.log('office initialized'); }; `

  2. Your second suggestion doesn't have any affect. I added in "taskpane.html" file like this ` <!doctype html>

    Excel App

    `

If you share your email please then I can send my manifest file which will be pointing to our live server for further verification on your side. As mentioned before, we have same issue in USA office, UK office as well as in Asia office as we have deployed manifest file in Central Administration (organization level) so I am sure, its not related to bandwidth.

Please let me know if you need more detail.

Thanks once again.

savanetllc commented 2 years ago

@JinghuiMS please confirm as an expert. If I setInterval outside of Office.initialize method like this: ` const render = (Component) => { ReactDOM.render(

, document.getElementById("container") ); }; /* Render application after Office initializes */ Office.initialize = () => { isOfficeInitialized = true; render(App); }; **setInterval(function () { if (!isOfficeInitialized) { console.log('In SetInterval'); isOfficeInitialized = true; render(App); } }, 3000);** /* Initial render showing a progress bar */ render(App); if (module.hot) { module.hot.accept("./components/App", () => { const NextApp = require("./components/App").default; render(NextApp); }); } ` Will some part of Addin not work because office might not initialized?
JinghuiMS commented 2 years ago

@jayrathi This issue about "Tracking Prevention blocked access to storage " issue when calling Office.initialize . I can not repro in my side. Our customer doesn't call any existing Api, just fails to execute office.initialize, do you have any ideas about it to unblock our customer? Thanks.

wandyezj commented 2 years ago

@savanetllc

Per Initialize Add-In Documentation using Office.onReady() instead of Office.initialize, might make a difference.

Could you share the yoman generator command you used to set up your Add-in or could you share a GitHub repository with the repro setup? This will help us debug the issue.

savanetllc commented 2 years ago

Hi @wandyezj, thanks for your comments and it seems Office.onReady() did the trick. So I make Office.initialize an empty definition and moved initialization code in Office.onReady() like this:

` Office.initialize = () => { }; Office.onReady = () => { console.log('in initialize'); if (!isOfficeInitialized) { console.log('initialized'); isOfficeInitialized = true; render(App);
}

Office.context.document.addHandlerAsync(Office.EventType.DocumentSelectionChanged, function () {
    Excel.run(function (context) {
        var sheet = context.workbook.worksheets.getActiveWorksheet();
        //further code
    }).catch(function (error) {
        console.log(error);
        if (error instanceof OfficeExtension.Error) {
            console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
    });
});

Excel.run(context => {
    var sheets = context.workbook.worksheets;
    sheets.load("items/name");
    var activeSheet = context.workbook.worksheets.getActiveWorksheet();
    activeSheet.load("name")
    var cell = context.workbook.getActiveCell();
    cell.load(['address'])
    return context.sync()
        .then(function () {
            if (document.getElementById("txtActiveCell")) {
                if (cell.address)
                    document.getElementById("txtActiveCell").value = cell.address.replace(activeSheet.name + "!", "");
                document.getElementById("txtSheetName").value = activeSheet.name;
            }
            if (sheets.items.length >= 8) {                    
                //Now we can enable Ribbon buttons for this workbook
            }
        });
});

}; `

So now taskpane loads successfully. But as you notice I have DocumentSelectionChanged event bindings as well as enable few ribbon buttons for specific Excel Workbook in Office.onReady. However even though taskpane loads but sometimes I got following errors so Office specific functions doesn't work. _Uncaught TypeError: Cannot read properties of undefined (reading 'document') at Object.Office.onReady (taskpane.js:2:549904) at commands.js:2:492028 at commands.js:2:496686 at commands.js:2:496690_

_Uncaught TypeError: Cannot read properties of undefined (reading 'addHandlerAsync') at Object.Office.onReady (taskpane.js:2:549913) at t (excel-win32-16.01.js:26:1261036) at Object.t.default (excel-win32-16.01.js:26:1261960) at excel-win32-16.01.js:26:1253848 at Object.OSFAriaLogger.AriaLogger.EnableSendingTelemetryWithOTel (excel-win32-16.01.js:26:1253852) at n (excel-win32-16.01.js:26:1252490) at excel-win32-16.01.js:26:1253282 at excel-win32-16.01.js:26:1253291_

Is this the right place for such event bindings?

JinghuiMS commented 2 years ago

Happy to see we find the right expert for this issue. Thanks @wandyezj for unblocking our customer. I assigned this issue to you to better handle it. Feel free to assign back or ping me if you have any concerns. Thanks.

wandyezj commented 2 years ago

@savanetllc could you please share a GitHub repository with the code and steps for a repro of the current issue you are facing? Having a repository with the code and steps to repro will help us understand and root cause the issue.