AngularJS initial route controller not loaded. Subsequent ones are fine - javascript

I have a HTML5 pushState app. For some reason or another, the controller responsible for the route that I hit initiall is not loaded when I first load the up. If I click around, everything is fine.
I'm not exactly sure why this is happening, a demo can be viewed here: http://osumo.paas.allizom.org
This used to be okay. I did some work today on some components that had nothing to do with the $routeProvider and it just broke.
Does anyone have any ideas?
Thanks.

So to answer this question, it gets quite.. interesting. The problem actually came from this line: https://github.com/shuhaowu/osumo/commit/c539d8048696152ad75f13a6d965160381b89a21#L2L22
The reason of this is actually quite logical, though it is a big pain to figure out. Basically I'm doing things that I should not be doing (as often that happens).
So first thing first, the code is setting a locale when a service is being initialized. That itself is no big deal, as we want to set the locale to navigator.language. This code is here: https://github.com/shuhaowu/osumo/blob/c539d8048696152ad75f13a6d965160381b89a21/static/js/develop/services/appservice.js#L165
When this gets called, an event gets triggered and this event will cause a bunch of directive to change its texts. Again, this is no big deal. https://github.com/shuhaowu/osumo/blob/c539d8048696152ad75f13a6d965160381b89a21/static/js/vendors/l10n.js#L23
Here comes the trouble. The version of the code that's problematic included $rootScope.$$phase || $rootScope.$apply() as when the library is designed it is assumed that setLocale could be called outside of the angular world and it wants to be a little magical so that things just works when the event fires. While I cannot be certain exactly what is going on in Angular, my guess would be that $scope.$$phase is not set at this point as we're still initializing the different components. Calling $apply here caused angular to start applying to the page, which causes the page to never load.
Lesson learned: don't do stupid stuff.

Related

Loading image is shown too late for users with slow connection

The issues is with existing ASP.NET MVC 4 project. The View itself is not that big but there are also several service calls and what happens is that people with slow internet connection reports that for some period of time when they request the page it stay unresponsive, so they don't know if the content is loading or something went wrong.
So in general, what I need is a way to show a loading image as the very first thing from this page (or at least fast enough) so even if it takes some time for the browser to download the full content, at least the user will know that something is going on.
However it seems that this is not as trivial as it sounds. I came up with two ideas, one was already proven to not work in all cases and the second is also something that many people doesn't recommend.
What I've tried was to use pure JavaScript in the <head> tag like so:
<html>
<head>
<script>
document.write("<div style='margin-left: 50px; margin-top : 50px;'>LOADING...</div>");
</script>
</head>
Of course the styling is just to get the idea. This seemed like it was working until recently when on a minor build of IE 11 the page broke which after some investigation was proven to be due to the usage of document.write() inside the <head> tag. Even though this seems to work on most browsers and versions the fact that it's a potential danger requires a change in the approach.
The second idea is pretty similar to this, again - writing directly in the <head> tag but this time instead of using document.write() just putting the html markup directly there. From what I've read this is also a recipe for disaster so I don't even want to try it, but those are the two ideas that I could came up with. Everything else just doesn't work for slow internet connections since the mainstream solutions relays on the fact that some part of the DOM is already loaded so you can use it to apply behaviour/style.
I hope I'm not the first one that got this problem so I would appreciate any suggestion on how to solve this issue. Since I am using ASP.NET MVC 4 there was an idea to use a dedicated controller with view which to get called first just for the sake of showing the loading image and then moving to the requested view. Even though this idea seems interesting I didn't have the time to think it over, it also sounds a pretty complicated, but anyways, all help will be appreciated.
When faced with the same issue, we did as you mentioned: Load a super-light-weight page first with a tiny loading icon & "Loading..." text, then called back to the server to pull down the heavy content in chunks using ajax.
If you content is really heavy, it's also worth mentioning that you need make sure you have gzip compression turned on at your web server layer also.
Don't block the rendering of the DOM. Load the page and call your scripts right before the closing body tag and attach to an event like DOMContentLoaded or window.load (if you're using jQuery, that would be $(document).ready). In other words, you should allow the page to load completely, even if it's empty, before running any of your JavaScript.
Then, don't worry about writing the "Loading" div dynamically. Just include it in the rendered HTML and hide it initially. The first thing your JavaScript will do, before issuing any AJAX calls, is to show this "Loading" div.

JS Script execution order on displaying from cache

I am writing a rail app making trees, with bootstrap and jsPlumb.
I have this problem, when displaying a page for the first time, everything works perfectly. When I go again on a page, some code is not properly executed.
This happens with both jsPlumb and bootstrap-tagsinput: a simple tagsinput on a page is not displaying properly.
If I hit refresh, then the page loads properly again.
I tend to think this is related to the fact that when I display a page with some cached elements, some of the script are not executed, or are executed in the wrong order, but I have no clue about it, since I can't see any error.
Hence the questions,:
How can I check that everything is properly executed (i used the console.log, the function are called)?
Is there anything to know about the way the cache may have an effect on script?
How can I debug this type of problem?
Thank you!
I found the answer, this was due to turbolinks, which handles some of the caching on the server-side. It was a holdover gem that I suppressed, and the problem is gone.

Polymer/platform.js breaks jQuery on Firefox

I seem to have reached a showstopping bug with Polymer in my current project, and none of the solutions I've found have worked.
Essentially, whenever I load platform.js alongside jQuery, I get the following error every time I click anywhere on the page:
TypeError: elem.getAttribute is not a function
elem.getAttribute( name ) :
jquery-2.1.1.js (line 1430)
Now, this doesn't actually prevent any of my code from running, but it freezes the page for about half a second, which is obviously unaccaptable since it's triggered by every click event. I can't have my UI take half a second to respond to click/touch events.
I'm aware that there is already a question addressing this issue on SO, but I've already wrapped the one occurrence of document in my code as per the accepted solution, and nothing has changed.
I've already decided to stay the hell away from Polymer for the foreseeable future because of various bugs like this and lack of polish in general, but I can't just drop it now because I'm already using a lot of custom Polymer elements. Can somebody please help me get this resolved?

ng-repeat not working with Firebreath plugin object

I am just beginning with AngularJS and I am trying to use ng-repeat on the Firebreath plugin and it doesn't seem to work.
<div ng-controller="PluginCtrl">
<object type='application/x-sometype' ng-repeat='plugin in plugins'
id='pluginobj_{{plugin.id}}'>
</object>
</div>
And my controller file has code which looks like:
var app = angular.module("appName");
app.controller("PluginCtrl", function($scope){
$scope.plugins = {};
$scope.plugins["1"] = {id: "1"};
$scope.plugins["2"] = {id: "2"};
});
I know this is an issue with Firebreath's JSAPI because it works really well if I change the object 'type' to something else. I did not go deep down yet on what's the cause of this but I guess some of the object dom properties angularJS needs when computing with ng-repeat is missing in the JSAPI. It would be helpful if someone knows why this is the case or already came across this. Thanks in advance.
Edit: By not working I mean the {{plugin.id}} is not being substituted by the values 1 & 2 from the scope, though two object elements are being created in the dom.
This is actually not JSAPI specifically, it's plugins in general. I doubt that it would work with Flash either. I am not 100% certain of that, but I did at one point spend a day or so trying to fix it and ended up just getting deeper and deeper into some of the weirdest issues I've ever encountered.
The number of reasons why this would be a bad idea is longer than I can even remember, and I wrote FireBreath. Suffice it to say that it is not likely to ever work well to do what you're doing. For one thing, you should never set the type of an object tag before adding it into the DOM because the browser in some cases (depending on browser, OS, and version) will actually reinstantiate the plugin instance when you remove it and add it elsewhere, which angular will tend to do in certain cases.
I really recommend only using a plugin by injecting the html directly in, or, if you won't accept that, setting the type after it's been rendered. You should be able to rig up a directive to make this happen however it needs to, including if necessary adding multiple instances of the plugin.
You are also welcome to spend some time trying to fix it; I have already done so, and I don't consider it worth my time to spend any further time on it.

TinyMCE remains hidden (uvw-dialog-open)

Ok i've developed a nice tinymce-solution, where i create and destroy all the tinymce-instances programmatically through js - so, i know it is maybe not the daily-usage of a tinymce implementation - but basically it works like a charm.
Now, before i will give you specific example code - i will explain my strange issue: A friend of me is an extreme power-user of the online-tool i made and he is creating/destroying hundrets of tinymce-instances during the day...
Sometimes, after hours of work, he has the behavior, that tinymce won't show up when he hit "edit"-button. I never made it, to reproduce that on my own - but one day, in a teamviewer-session, i was able to have a look into his screen and page (with firebug), when the error already happened.
So, badly i was not able to make a full debugging through the javascript-code (because when you hit one times f5 in this situation, the error disappears and it will take some other hours to get it again) -> i realized, that, when the error was happened -> everything in the tinyMCE-object itself seems ok -> also everything in the DOM-rendering seems ok -> BUT, from some strange css-import-file, there was suddenly a definition like this:
html.uvw-dialog-open object, html.uvw-dialog-open iframe, html.uvw-dialog-open embed {
visibility: hidden;
}
This is causing that a main-panel of tinymce won't show and nothing of tinymce is visible anymore.. killing and recreating of the instance won't fix the bug in this moment, you must press f5 and after a reload, you even can't find this css-definition again (or, at least, i was not able over teamviewer and his shitty, small laptop)
So, the only thing that came in mind was an ugly hack in my own css, telling this:
html.uvw-dialog-open object, html.uvw-dialog-open iframe, html.uvw-dialog-open embed {
visibility: visible !important;
}
And, since then... it was quite for weeks -> but today, my friend calls me again, telling me, that he can't see tinymce, AGAIN.. i was almost in tears, you can imagine :D
Ok.. after writing and re-reading all these lines -> i realize that my fix won't work... both are the same definitions and if they appear on the same level (file, not inline).. probably last-match-wins i guess, what would be the newly, lazy loaded tinymce-file.. so it will definitly be better, to make an inline visibility:visible; over the init_instance_callback of tinymce...
But, in my desperation, i thought i will write everything down here on stackoverflow -> maybe someone knows the real cause of this issue and.. you guys are the most awesome devs out there i know :D
Jebbie,
Thoughts more than a definitive answer ...
Sounds like a memory leak issue due to lots of javascript/DOM activity in a long-lifed page.
You've probably done nothing wrong and you're unlikely to track down the actual cause, however certain measures are available to you :
Try making your tinymce instances reusable rather that destroying and creating new every time.
Periodically have the page request a re-serve - it may be a challenge to reproduce the entire document state - DOM and javascript environment - in the re-served page.
Lots of work and no guarantees I'm afriad.

Categories