Meteor load order running counter to documentation and other anamolies. Full example included - meteor

I still can't quite get Meteor's load order fully under control. I use a lot of 3rd-party scripts when using Bootstrap templates with animations and a lot of these scripts break because they are created with the traditional load order in mind for DOM nodes.
Meteor does not follow this traditional load order, so a lot of times DOM nodes aren't ready when the scripts fire.
I made a simple Meteor app that console logs a message each time a script inside of a particular folder or template.rendered callback is loaded.
https://github.com/fuzzybabybunny/meteor-load-order-test
You can see it deployed here (open up Chrome Console)
http://load-order-test.meteor.com/
There are a few strange things going on.
main.js and main.html are actually loaded very soon, counter to what the documentation says: http://docs.meteor.com/#/full/structuringyourapp
all the DOM nodes are actually created earlier than expected
with six templates that still have yet to have their .rendered() callbacks fired, the max number of DOM nodes has already been reached. We should expect more DOM nodes to be added with each .rendered() callback being fired.
Can someone help explain why I'm seeing these strange things?
Also, is there a surefire way to only run a script once all DOM nodes have been created? Currently it seems like using jQuery to append <script> tags somewhere on the DOM inside of Template.Layout.rendered would be the most foolproof.
Template.Layout.rendered = function(){
console.log('layout template rendered and the number of DOM nodes is ' + document.getElementsByTagName('*').length);
$('head').append('<script src="/javascript/domCompleteScript.js"></script>');
};

Per the documentation, slightly further down the page:
client/lib/ # code for the client to be loaded first
This folder is for compatibility JavaScript libraries that rely on variables declared with var at the top level being exported as globals. Files in this directory are executed without being wrapped in a new variable scope. These files are executed before other client-side JavaScript files.
I would try putting the 3rd-party scripts into the following places, just to see what works best:
client/lib
client/compatibility
lib

Related

Handlebar objects not working when linking to a script by an URL

There are 2 ways to use a script with in a script manager
linking to a script by an URL
manually entering in the script.
The handle bar objects don't seem to work while linking to a script by an URL but works when manually entering it. An example script is very simple as below:
console.log("{{product.id}}");
I just wanted to find a solution or a workaround to make the handlebar objects work seamlessly when the script is hosted on a CDN.
Screenshot below:
Consider using 2 scripts. One is an inline script to instantiate certain JS variables your CDN script needs, and the other is your CDN script which checks for window.your_data when it evaluates.
So your first script might be:
<script>
window.currentProductName = "{{product.name}}";
</script>
And your CDN script will check for window.currentProductName when it evaluates.
As script order is not guaranteed within the same insertion target, it's best to put the inline script in the header and the CDN script in the footer (generally better for site speed as well).
I'm not sure if this is what you're looking for but you should be able to accomplish this with the inject & jsContext handlebars helpers. See both here, with a 'console.log' example.
https://developer.bigcommerce.com/stencil-docs/reference-docs/handlebars-helpers-reference#inject
When you reference a script via the URL option it is added to the page via a script tag. This means it gets loaded and run on the client side as the page loads. It would not have access to handlebars.
When you directly enter the script in the manager it is first processed server side and the result is directly placed on the pages. It does have access to handlebars.
You may want to do a combination. A manual script to gather and store the data you need, then a url script to load the main js that can access the data you stored.
You could merge them as one by having the manual script dynamically add the script tag for your external script.

Meteor iron-router IRLibLoader loading external JS files but none of the DOM elements inside template are loading

I am using the meteor package IRLibLoader. It works great loading all of my external JS. I am able to call all of the JS functions from dev console to confirm that they are actually available. The problem... all of the DOM elements , for example div tags with id = foo.... I am unable to select any of them , they are all coming up undefined. The page is getting stuck to loading. Any ideas?
I ended up over complicating my issue.
The simple solution was for me to add the MyProject/public folder to my Meteor application.
For example:
MyProject/public/images/foo.jpg
I was then able to serve the content via the public folder and when any of my app needed access i would just put for example :

Meteor: [Load Order] Make JavaScript file load after HTML file is loaded?

Load Order Issues
I am having trouble making Meteor load my JavaScript after my HTML file fully loads when I go to localhost:3000. The problem is that my JavaScript keeps loading before my HTML file, and makes the page look unloaded when I use stuff like alert(); or prompt();. I've tried a lot of solutions such as naming my JavaScript file as main.js and putting my HTML file in a deeper directory and using <script> tags. I have also read the documentation concerning this: http://docs.meteor.com/#/full/structuringyourapp Solutions I've tired based off the documentation such as putting files in client/lib , client/compatibility , and lib have proven to no avail. I also tired Meteor.startupand I placed the file for it in the client folder. (The code inside it):
Meteor.startup( function () {
$.get("client/lib/testproject.html")
$.getScript("client/testproject.js");
});
The above sort of solved my problem, but it loaded the JavaScript file two times. The first time was before the HTML loaded and the second time was after the HTML loaded. I don't know a way to prevent the first JS load from happening when using Meteor.startup, so any solutions for that are also appreciated.
The JavaScript file's code I am referring to is simple. (In it's entirety):
prompt("Hello World!");
myList = ["apples", "oranges", "bananas"];
myList.forEach(function(value, index) {
alert('I have ' + value + ' for dinner.');
});
Summary
To summarize my problem:
My Problem:
Go to localhost
JavaScript loads first
HTML loads second
What I Need:
Go to localhost
HTML loads first
JavaScript loads second
The Question: How can I make my JavaScript load only after when my HTML is loaded? And how can I restructure my folder, file-names, and/or code to make it behave as I want it to in this case?
Since the code posted is extremely simple to reproduce I kindly ask that you
run your own solution with a setup similar to what I have and not something that uses a million packages since that is unnecessary for my case, on Meteor, before responding to this.
I'm on Meteor 1.1.0.2
Here is a link to my folder structure with included HTML code along with filenames I used: http://i.imgur.com/24z6bXF.png
I think you missed a decisive information : you should wrap your Javascript code into a Template.yourTemplate.rendered=function () {} function.
That is the meteor way to ensure that your related html code is properly rendered first.
First of all, Meteor will always repackage your files and load them automatically in a specific order (Meteor structuring your app). First files in client/compatibility then client/lib and then the others JS files.
You should also rewrite your code so it does not get executed immediately at load time, like wrapping everything in a function. And then, you should call this code when the DOM is loaded, which does not necessarily mean in Meteor.startup but also in onRendered callbacks in your templates.

Combine web server controls web and script resources (axd files)

I know there are lots of similar questions like this in the web, but I haven't got to one working solution after searching for these last 2 days. Some threads are outdated, others solutions don't work, others are too complicated to manage, so... Yes, another question about resources.axd files in asp.net projects.
I'm starting to build a set of server controls and embedding some resources. After building my controls and dragging them into pages, each individual resource is requested by the browser in the form of an .axd script. I understand the part where the ScriptManager manages these scripts and they're not ready to use, for instance, in Bundles in some sort of .Include("*.axd").
I tried some of the combine/minify/compress/gzip/icecreamOnTop packages out there but couldn't manage none of them to work.
I tried the StriptManager CompositeScript approach and the ScriptResources.axd are indeed combined, the response is successful (code 200), but in the end the scripts don't work. Example: I included the jQuery lib in that composite script and then tried to use it in the page - didn't work. I must say I didn't reference () the composite script anywhere because I didn't understand how to do it. If I set the path, then a 404 was returned (found the 1024 byte limit threads, etc...) and all the requests to the WebResources.axd would still remain.
I would prefer not to write an HttpHandler myself.
Also tried to download the AjaxToolkit and tried the ToolkitScriptManager which combines scripts, but that added ~4seconds to my page load. No, thanks.
My question is: what is the current approach regarding this matter in .net 4.5?
I will have lots of resources and would like to combine them. All js and css files in the final website project are bundled, but how to 'bundle' the axd files?
Here's a little example which will make the following requests:
Click here to view image
I know I can set the AjaxFrameworkMode to Disabled and will only have the 2 first WebResources.axd requests in this example, but what about when I have 10 css files embedded in my controls?
Any working solution would be much appreciated.
Many thanks
I managed to implement something that suits my case. More of a work around than a proper combining solution, but works and that's good enough for now.
All my controls extend a base class which has a property called ProcessResources. By default this property is set to true. That means that JS and CSS resources will be registered and each control has everything to work as standalone (axd resources will be generated). When set to false, no resource is registered and no axd files are generated.
The base class also has a static method that receives a destination path as a parameter and copies all the JS and CSS resources to that folder (if they don't exist or have been modified). This method returns a collection of all the needed resources for the control to work.
This way, on Application_Start, I can do something like:
myJsBundle.Inlude(ServerControlA.GetResources("~/ExternalResources", RESOURCES.JAVASCRIPT));
Then just need to set the ProcessResources flag to false (each control or web.config). All resources are now bundled and no axd files are generated.

Drupal - customizing $scripts output

Basically the issue im having is I have a custom theme, and I need to use $scripts to call the analytics code at the top (the link tracking settings) however this also loads loads of other cr*p js files I dont need or want.
All I want is the analytics stuff the module places in $scripts.
So can I somehow either:
A) Load only the analytics code via $scripts (.info file?)
B) Create a new region in .info file (e.g. $analytics) and call that via the template. But then how do I get the analytics code to output to this new region instead of $scripts?
Any help would be most appreciated.
A.
I would be wary of not outputting $scripts. The files that are output are needed for your other modules to work properly. If you want to reduce the scripts which are output then turn off modules that you don't need.
I agree that disabling the $scripts variable (or cleaning it out) will have some "undesired results". I can think of about half a dozen modules that I use on every build that have required js files.
Maybe you should look into the Google Analytic Module which uses the $footer variable instead of the $scripts.
http://drupal.org/project/google_analytics
I also use this module on all my builds as it provides some very easy integration of Drupal into GA including downloads, user roles, etc. (out of the box)
p.s.
Remember Drupal has a pretty good Performance settings that allow for the cache as well as consolidation css/js.
My final builds have 1 line of markup that calls ALL of my css for that page and one line that does the same for my js. It's been shown that consolidating your asset files into one large file rather then many small ones is a huge performance saver, more so then the size of the end file itself.

Resources