Please give a brief summary of your issue:
Hi there,
We need to use a config file in our deployment of apryse because we need to serve the static assets from a different URL. When we do this, we have found that the standard instructions don’t appear to be working with a config file. The app throws the following error after our initApryse function is called - ReferenceError: instance is not defined. How are we supposed to access the instance if not using a global instance property as suggested in the docs?
Note: We did add an entrypoint in our webpack.config in order to add the config file to our bundle. Could this be the source of the issue and if so, how do you recommend we package the app with webpack when using a config file. I have tried a minimal config file in both typescript (which we’d prefer) and javascript and both failed with the same error.
Please describe your issue and provide steps to reproduce it:
Please provide a link to a minimal sample where the issue is reproducible:
// src/apryse/apryse.config.ts OR src/apryse/config.js - BOTH FAIL
declare const instance: any
instance.UI.addEventListener(instance.UI.Events.VIEWER_LOADED, () => {
console.log("this should work"); // it doesn't - throws a "instance is undefined" error in the browser
});
// webpack.config.js
{
entry: {
app: "./src/index.tsx",
apryseConfig:"./src/apryse/apryse.config.ts" // OR "./src/apryse/config.js" BOTH FAIL
...},
}
// calling function
initApryse = (viewer: HTMLElement) => {
logger.info("Initializing apryse");
return WebViewer({
licenseKey: // license-key //
path: path,
config: "/apryseConfig.js"
}, viewer)
.then(() => logger.info("Initialized Apryse successfully")
Webpack’s bundling process can break the config file’s availability or format, causing issues like instance not being defined.
The config file should be a plain JavaScript file (not TypeScript as it needs to be executed directly from browser context) and should not be bundled/modified by Webpack.
I recommend moving your config file out of the Webpack build process, serve it statically (like the other static assets), and reference it via the config option in WebViewer.
See this guide for accessing the instance in the config file:
So I’m in progress with setting this up with a test environment but still am unable to get it working locally, we’re getting the same undefined instance error when running the dev server. I moved the same eventListener into a plain /static/config.js js file and served it using the static property of the webpack devserver so there shouldn’t be any bundling to my understanding (please correct me if I am wrong) . Do you have any suggestions or do you have any sample projects I could refer to using webpack and the config deployment method of Apryse?
Also, shouldn’t this error be thrown by the WebViewer constructor? I’ve set this up using a regular try {...} catch(e){...} block as well as a promise.then().catch() and neither catch the reference error. Never mind, fixed this with a try/catch block in the config.js file.
Hi Kevin,
Did you link the wrong sample project, the readme.md mentions a config.js file but there isn’t one in either of the directories, nor does the app load from config.
Also just FYI there’s a bug in this sample - this line should be path: 'http://localhost:8080/lib/', not 8081
The config file URL doesn’t match the one loaded by WebViewer
if the config file is being run by the webviewer constructor then this can’t be the case right?
The file loads before WebViewer initializes this is taking place before a file is loaded, there is no initial file
The iframe cannot reach the URL the config code is being run so presumably this is not the case, also the network tab shows that the file is being retrieved successfully
The path to WebViewer assets is incorrect (i.e. iframe never fully loads)
Thank you for pointing that out. That sample project should have a config file but it looks to be missing, I will follow up with the team regarding that project.
If the config file loads (from the network tab) and the code runs, but the instance variable is still undefined, it may be possible that the config file is being called too early, before WebViewer is fully instantiated. Could you check if instance is available under the window object? (I.e. window.instance)
Please also make sure that the config is a JavaScript file.
Hmm, window.instance is returning undefined. I checked both before the constructor is called, after it completes (the config error doesn’t cause the constructor to fail) and even in the (plain js) config file as well.
They’re all undefined.
I also tried setting up the config file in the cors sample project and I seem to be having the same issues. Am I doing something wrong or is there a bug with using the config?
I made the following changes to the webviewer-cors sample
// Added new config file at
// webviewer-app/public/apryse.config.js
try {
console.log("INSTANCE IN CONFIG: ", window.instance);
if (window.instance == undefined && instance == undefined ) {
console.log("Instance is undefined in config");
} else {
instance.UI.addEventListener(instance.UI.Events.VIEWER_LOADED, () => {
console.log("Viewer loaded in config");
const url = 'https://pdftron.s3.amazonaws.com/downloads/pl/webviewer-demo.pdf';
instance.UI.loadDocument(url);
});
}
} catch (error) {
console.error("Error accessing instance in config: ", error);
}
// modified app.tsx to use the config
// webviewer-app/src/App.tsx
useEffect(() => {
const configPath = process.env.PUBLIC_URL + '/apryse.config.js';
WebViewer(
{
path: 'http://localhost:8080/lib/',
config: configPath
},
viewer.current as HTMLDivElement,
).then((instance) => {
console.log("Webviewer instance created in app??");
const url = 'https://pdftron.s3.amazonaws.com/downloads/pl/webviewer-demo.pdf';
// original file continues to load webviewer-demo.pdf and initialize annotation manager
// added a script tag to load the config file in public
// webviewer-app/public/index.html
<script src="%PUBLIC_URL%/apryse.config.js" ></script>
When I run the app with the following changes the constructor is run and the config file is loaded and immediately logs INSTANCE IN CONFIG: undefined then catches the Error accessing instance in config: ReferenceError: instance is not defined error.
In App.tsx. the .then() block runs after the constructor completes and will load the document normally as if there isn’t a config file there at all. If I remove the .then() block then apryse initializes in the app without loading a file (see screenshot of the app being run with the .then() block comment out )
It looks like the issue is that with the newer WebViewer, it is instantiated as a Web Component instead of an iFrame. This means that you will need to grab the instance variable from the global WebViewer object as shown in this guide: