Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate PDF after "view-ready" event does not work #169

Closed
henryqdineen opened this issue Feb 13, 2017 · 11 comments
Closed

Generate PDF after "view-ready" event does not work #169

henryqdineen opened this issue Feb 13, 2017 · 11 comments
Milestone

Comments

@henryqdineen
Copy link
Contributor

I just can't seem to get this to work in any way. It will always wait the full 10 seconds.

Has anyone else been having problems with this feature?

@codecounselor
Copy link
Collaborator

Can you include your code from your app where you emit the event?

@henryqdineen
Copy link
Contributor Author

Thanks. Here is a basically what the code does:

const element = <div>Test</div>;
const node = document.querySelector('.page');   
ReactDOM.render(element, node, () => {
    document.body.dispatchEvent(new Event('view-ready'));
});

even if I take it out of the callback the behavior is the same. It will always wait for 10 seconds or up to whatever --outputWait is specified as.

@codecounselor
Copy link
Collaborator

Have you set the --waitForJSEvent option? If you don't do that it will not trigger the event. I actually use --waitForJSEvent=ready
And if that is not it, have you debugged this in Chrome to make sure its being invoked? It looks correct to me though.

There is a test html page which you can also look at, run this command to try it out: ./cli.js ./test/event-test.html ./output.pdf -e ready -w 5000 --browserConfig '{"show":true}' && open output.pdf

@codecounselor
Copy link
Collaborator

But if you want to use view-ready you can just omit the value and set -e or --waitForJSEvent

@henryqdineen
Copy link
Contributor Author

thanks @codecounselor.

I think I got it to work by wrapping the dispatchEvent in a setTimeout like in your event-test.html

ReactDOM.render(element, node, () => { setTimeout(() => { document.body.dispatchEvent(new Event('view-ready')); }, 100); });
I tried a couple different timeouts. 0 and 10 didn't work but 100 did. Any thoughts on why this would need to be in a setTimeout? Any what would be the best value to use for a delay?

Thanks again.

@codecounselor
Copy link
Collaborator

Well I'm not a react expert but I know it uses a virtual dom so my guess is that when this runs in your render method perhaps document.body is not in the correct state?
Perhaps you should try putting it in a component-did-mount lifecycle hook
https://facebook.github.io/react/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class

@henryqdineen
Copy link
Contributor Author

henryqdineen commented Feb 13, 2017

@codecounselor This still happens even if I totally remove React from the app.

I wonder if it is some sort of race condition?
From exportJob.js:
win.webContents.on('did-finish-load', waitFunction)

maybe this dispatchEvent happens before the addEventListener?

@codecounselor
Copy link
Collaborator

That is a possibility, and might explain an issue I'm seeing as well. I will investigate this further and provide an update tomorrow.

@codecounselor
Copy link
Collaborator

So as suspected, there is a race condition here where the main process does not send and execute the javascript in the renderer process (browser) before the page is loaded and emit's the ready event.

I think what I'm going to do is add an acknowledgement event (${waitForJSEvent}-ack) that the page can listen for. This will require the application to send the ready event repeatedly on some interval until the ack is received.

In the sample html page referenced above that would look like this:

var eventEmitInterval = setInterval(function () {
    document.body.dispatchEvent(new CustomEvent('view-ready', {}))
	document.body.innerHTML += 'view-ready emitted...'
  }, 10)

  document.body.addEventListener('view-ready-ack', function(){
    clearInterval(eventEmitInterval)
  })

I'm not sure if there is another way to solve this, I will look a little bit deeper. But so far I have found nothing in the electron APIs that is of value.

codecounselor pushed a commit to codecounselor/electron-pdf that referenced this issue Feb 14, 2017
codecounselor pushed a commit to codecounselor/electron-pdf that referenced this issue Feb 14, 2017
@henryqdineen
Copy link
Contributor Author

awesome. Thanks for the help. We are really excited about using this library and fixing this definitely helps.

codecounselor pushed a commit to codecounselor/electron-pdf that referenced this issue Feb 14, 2017
@codecounselor
Copy link
Collaborator

This has been released to npm as version 1.1.8 - note the change from -ack to -acknowledged

@codecounselor codecounselor added this to the 1.1.8 milestone Feb 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants