0

I need to run a simple java script function after my react form has finished loading. The JS is loaded from a 3rd party so i have no control over it and i need to run one of its functions in order to make a captcha section appear in my form. If i hit F5 then the area appears as expected but navigating to the page via the routes in the app does not trigger the load.

I have worked out that if i call this line of JS

window.__challenger.callPageRequest();

Then the captcha area appears, i know this works as i added a temporary button to the form which is being render and call the funtion on the button click. But I can't have some random button, i need to just fire this JS line everytime the form is navigated to.

I've tried using:

componentDidMount() {
    window.__challenger.callPageRequest();
}

But that complains with:

Cannot read property 'callPageRequest' of undefined

And i've tried adding:

window.__challenger.callPageRequest();

to the end of the form in the render method.

why is it so hard to do such a simple thing? any helped would be very much appreciated.

JPT
  • 121
  • 2
  • 12
  • 3
    Which Captcha library are you using? My suspicion is that `componentDidMount` is being called before the JS for the Captcha library has finished being processed. – Matt Holland Mar 20 '18 at 17:13
  • Unfortunately it an in house system developed by our colleagues in Japan, we have no way of getting it changed at all without mounds of red tape and weeks of delay. So effectively it’s like a 3rd party. – JPT Mar 20 '18 at 17:44

3 Answers3

2

Are you sure componentDidMount is running after the route change? A route that is only different from other routes because of different params does not remount. You could try the componentWillReceiveProps() lifecycle method instead.

Trey Eckels
  • 348
  • 3
  • 10
  • Yes, I made sure componentDidMount was firing, as you suggest will try the compontWillRecieveProps. Thanks – JPT Mar 20 '18 at 21:16
1

Short of bringing redux and an additional component that dispatches actions on script loads. The best I can think of just now, if you're using a script tag with an external src to load the script you could try adding a handler onto the script tag and render it in you render method (although this is a bit messy). You might need to do some this binding in your constructor. Caveat, I haven't tried this.

see this answer: Script load in react

Lesbaa
  • 1,979
  • 2
  • 12
  • 15
1

The easiest (and possibly hackiest) is to poll window and check for the presence of the function before triggering it:

componentDidMount() {
    const poll = () => {
        if(window.__challenger && window.__challenger.callPageRequest) {
            window.__challenger.callPageRequest();
        }else {
            setTimeout(() => {
                poll();
            }, 250);
        }
    };
    poll();
}

If it exists on the first pass, go ahead and immediately call it. If it doesn't exist yet, wait 250ms and then try again.

Chase DeAnda
  • 15,963
  • 3
  • 30
  • 41
  • This worked great for me. Not a huge fan of timers etc for this kinda thing but it’s got me out of a hole. Will carry on researching some of the other things people have proposed. Thanks. – JPT Mar 20 '18 at 21:15
  • Glad you got it working, I feel the same way about polling (notice the hacky comment lol), but when all else fails, good ol' vanilla js is there to fallback on. – Chase DeAnda Mar 20 '18 at 21:16