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

Javascript doesn't work client-side #299

Closed
damienbidaud6 opened this issue Oct 3, 2016 · 22 comments
Closed

Javascript doesn't work client-side #299

damienbidaud6 opened this issue Oct 3, 2016 · 22 comments

Comments

@damienbidaud6
Copy link

Hi,

I have a javascript file in my static ressources when I use it server-side or in local without open-component it work perfectly, but when I use the same component client-side the js is not executed and I don't have a error message in the console.

So my question is do they are limitation for the static ressources or a configuration issue who can block my js code the be executed client side?

thanks

@matteofigus
Copy link
Member

Hi @damienbidaud6 - how does your package.json looks like? If you need static resources, you need to declare the folders in the component spec. Example: https://github.com/matteofigus/oc-components-examples/blob/master/static-image/package.json#L14

@damienbidaud6
Copy link
Author

I have add the folder in the static field like you can see:

{ "name": "widget", "description": "", "version": "1.0.0", "repository": "", "oc": { "files": { "data": "server.js", "template": { "src": "template.html", "type": "handlebars" }, "static":["js"] } } }

@matteofigus
Copy link
Member

Uhm ok that seems ok. Other thing to check, in your component are you using the staticPath parameter to build the url? Here is a step to use a static resource step by step: https://github.com/opentable/oc/wiki/Advanced-operations#add-image-in-the-view-template

If all seems still good to you, are you able in case to share the code?

@damienbidaud6
Copy link
Author

I think have the same thing

here my server.js

'use strict'; module.exports.data = function(context, callback){ callback(null, { path:context.staticPath, init: { to: context.params.to || 7015400, from: context.params.from || 8727100, depart: context.params.depart || '01/01/1900', return: context.params.return || '01/01/1901', point_of_sale: context.params.point_of_sale || "XXXXX" } }); };

and my template.html

<div id="magnet"></div><script src="{{path}}js/index.js" language="javascript" type="text/javascript"></script><script src="{{path}}js/app.js"></script>

@matteofigus
Copy link
Member

@damienbidaud6 I can't reprodue. Created a test repo to see if I'm doing something different?
https://github.com/matteofigus/oc-issue-299

@damienbidaud6
Copy link
Author

I have modified and push the index.js and the app.js for have a situation closer to what I have and when I try to select the input he is not found but when I use the same selector in the chrome commande line it select the input.

@matteofigus
Copy link
Member

Ok, I think I now understand 👍

So, when you have 2 files like that and you do server-side rendering, execution is going to happen as soon as the files are downloaded, but the order is going to be guaranteed to be the right one.

When doing the client-side rendering, you may have a race condition for having file 2 downloaded and executed before file 1. To solve that, we usually follow one of those 3 approaches:

  1. Simplest one, you bundle all the JS to be a single file
  2. You use the built-in functionality for requiring CSS or JS files - like I did on this sample project
  3. You use any other customised way for ensuring dependencies are loaded in the right order, for example using any other library like require.js or SystemJS, or just emitting/subscribing to some events so that you get the orchestration right between the pieces.

In my experience, 1) is good for doing something simple, but when you start having multiple components in the page something like 2-3) is required.

Hopefully this clarifies 👍

@damienbidaud6
Copy link
Author

I try the 3 approaches and I have still a issue client-side with the js I have the beginning of the page who use the js correctly but the end doesn't use the js for example server-side I have this element who work perfectly
screen shot 2016-10-05 at 09 21 36

but client-side I have no interaction with the js
screen shot 2016-10-05 at 09 21 30

I look to the network tool and with something like 2-3 the js is loaded in the correct order but I have no interaction with the second half of the component when I use it client-side>

I hope it was clear

@matteofigus
Copy link
Member

I still can't reproduce. Just to double check, you tried the latest version I pushed here?
https://github.com/matteofigus/oc-issue-299

In case you did, are you able to upload there the real version of the app.js?
I can make that repo private if you want - just want to get something I can reproduce so somebody here like me or @mattiaerre can help you ;)

@damienbidaud6
Copy link
Author

I have a issus on oc-issues-299 when I try to load the page on chrome I have a error
screen shot 2016-10-05 at 14 51 18

my version of node is 4.6.0 and my version of npm is 2.15.9

@matteofigus
Copy link
Member

have you done an npm install and then a npm start next? I setup the npm start in such way it runs in parallel the oc dev in the port 3030 and an http server on port 3000

@damienbidaud6
Copy link
Author

yes and I have check if something was using the port 3000

@damienbidaud6
Copy link
Author

It's ok I try with sudo and it's work

@damienbidaud6
Copy link
Author

if you can make the project private I will push my app.js

@matteofigus
Copy link
Member

@damienbidaud6 done ;)

@damienbidaud6
Copy link
Author

I have push it

@damienbidaud6
Copy link
Author

they are only the first 2 input who have the js who work well the rest I have not interaction for example the button across the input of type number should increment or decrement the number and it does nothing but in a normal page it work well

@matteofigus
Copy link
Member

All right, I think I managed to reproduce! I think it may be something with the react chain of events. I'll look at it tomorrow with some fresh eyes and I'll let you know 👍 Thanks for being patient :)

@matteofigus
Copy link
Member

Ok, I think I now understand the problem 🎉

In the original files I see some points where there is a check for document.readyState with some bindings to actions for when the DOMContentLoaded event is emitted. The files are minified so I can't fully understand where and how to fix it.

Now...when I put a console.log(document.readyState) on the working piece I see loading but when I go to the OC client-side rendered component I see completed. This is because the OC rendering happens when the DOM is already there - so the react rendering happens with the document.readyState completed instead of loading. When emitting (as hack) the DOMContentLoaded event once again after the OC component is rendered, the bindings work perfectly!

So, I did something like that and worked with Chrome:

window.oc = window.oc || {};
oc.cmd = oc.cmd || [];

oc.cmd.push(function(){
    oc.require("{{path}}js/index.js", function(){
            oc.require("{{path}}js/app.js", function(){

                    var DOMContentLoaded_event = document.createEvent("Event");
                    DOMContentLoaded_event.initEvent("DOMContentLoaded", true, true);
                    window.document.dispatchEvent(DOMContentLoaded_event);
            });
    });
});

Now - I think the problem is either in the index.js or app.js. After pairing a bit with @mattiaerre and @nickbalestra they suggested as solution to possibly change the events handler in the react app (one of those two files) to listen to specific React events instead of relying to the document.readyState such as componentDidMount (example).

I updated the private repository with the hack so that you can have a look @damienbidaud6

@damienbidaud6
Copy link
Author

That's great thanks a lot for the help.

I will look for change the index.js.

And again thanks for the help.

@matteofigus
Copy link
Member

Hey, Pleasure! 👍

Let me know how it goes. Should I close this issue now?

@damienbidaud6
Copy link
Author

Yes I thing it's good.

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