Angular controller sporadically not loading - javascript

I have a website set up with RequireJS and Angular, but at seemingly random moments, it will decide to either not load part of the Javascript or not databind part of the angular code.
The page in question has several different components on it with their own angular controllers. Everything loads fine about 90% of the time, but sometimes something will happen that prevents databinding (angular brackets visible, ng-hide not working,...). Additionally, the 'network' tab in Chrome devtools shows no files being loaded, though they are listed in 'sources'. I don't know if that is relevant somehow. I get no errors in the console at all.
Digging around in the JS console I've found that one of the broken controllers in question does exist ( = I get an object using angular.element(...).scope() ) but when I try to access one of its properties, they are either undefined OR in case of the init() function I use in all my controllers, it returns the function of the parent controller.
What could cause the controller to be loaded but its scope variables to be undefined at seemingly random times?
EDIT:
The only way I've found to sort of reproduce this issue without errors showing up in the console is to initialise the controller as an empty function. This produces similar scope behavior in the console, but it doesn't cause the angular curly braces to show up. I will accept any clue that leads me to the cause of the issue or a viable workaround.

It appears that RequireJS sometimes loaded everyting fast enough for the angular.bootstrap call to be executed before the DOM was completely loaded. This lead to angular processing what is already loaded and ignoring whatever came next. I therefore added a domReady requirement to the setup so I only bootstrap angular when I know the whole page will be there. Since it is hard to know for sure, I can only hope this was the cause and that we won't be seeing this issue again.

You might have to use AngularAMD. Works great for our angular website.

Related

Does JIRA have a method to call JQuery(window).ready?

We have a Jura plugin written by ourselves, and in it's vm template at the very end there's the following code:
AJS.$(window).ready(function(){
doSomeThing();
});
Inside of this method we are loading some server side data and initializing internal js objects. For some strange reason this specific method doSomeThing is being called twice. Moreover, vm template is also being called twice, owerwriting first template initialization state (but template may be already initialized and contain some data at this point). I don't get it why it's made this way and how to work around this. If someone faced similar thing before and knows what to deal with it - please respond. Much appreciated.
We've found a reason of such bahavior - it's Backbone. Jira creates an element using Backbone View, which calls AJS.$().ready second time during initialization. We stopped usage of this element after our investigation

Laravel App not always showing my changes in real time.. caching?

I am learning AngularJS and having a weird problem whereby sometimes if I make a change in my JS files, the change doesn't apply.
I can see the GET request to the file through the console however it still contains old content. I can even remove everything inside of the file and the application still shows old content. It's only when I delete the file that it recognizes that something is wrong.
Is there some sort of caching going on that I need to know about?
I am using Laravel 5.1 however at this point, Laravel is really only handling the routing at this point.
Eventually, the changes come through. Am I going crazy or is this one of the gotcha's I should know about with AngulasJS?
Try:
$scope.$apply()
The way angularjs works is when one of the binded fields (ng-model) is changed in the browser, angularjs updateds the data model in the scope (controller or directive).
If you have code with callbacks when the new data is to be assigned to the data model, you'll need to run $scope.$apply(). This statement tells anguarljs to rebind the data model to the view (html).
Depends on where you have the $apply statement, you might want to test for $scope.$$phase because if the digest/apply is already in process and you run $apply, you'll get a Javascript run time error.

Angular - Lazy loading an entire page from CMS

I'm attempting to build an angular app that is driven by the CaaS/CMS known as Prismic.io.
Phase one of this project will be a straight forward content-silo (CMS-managed), and phase two will add on more complex web app components. Knowing this, I've decided that Angular would be my best bet, but I'm struggling to think of a good solution to have all of the content lazy-loaded from the Prismic API.
One solution I've decided to explore would be to have a standardized $scope variable, let's call it $scope.loaded. Each controller will do what it must to query my Prismic service for its respective content, and once it's completed, it would set $scope.loaded = true.
The part I'm stuck on with this approach is how exactly to display the page while all of these components are loading. The easiest way would be to include ng-if directives that reference this loaded value, but I feel like there'd be a massive flash of unstyled content. And yes I could use spinners, but the idea of having 90% of the page covered in spinners seems chintzy.
Then I got to wondering: what if I pull up a loading screen for the app until all controllers' $scope.loaded values are truthy? In that case, how would I know which controllers are currently active on the page and reference their respective scopes?
(If you have comments about why this approach is bad, I'd love to hear them as replies rather than answers. I imagine this could create too many http request, for example).
A couple of options here:
Have you looked at ngCloak to see if will help you here with the flicker problem? https://docs.angularjs.org/api/ng/directive/ngCloak.
If you're using jquery, you could have a global spinner that works on concurrent ajax requests http://api.jquery.com/category/ajax/global-ajax-event-handlers/.
Or have a look at something like this global angular spinner https://github.com/monterail/angular-global-spinner/tree/master/src.
If none of these work, you could always create an array on the root scope where each controller/directive registers itself and sets its loading flag. Then add a watch to that variable to see when all components in that array are finished loading.

How to display page's content after controller variables are initialized

I'm new to angularJS and web in general so I'm interested if it's possible to display page after it's controller's $scope variables are initialized?
The thing is most of my $scope variables are used to manage dynamic look of a page. It comes to page is loading right on my eyes, and I realize things loading are my $scope things.
Is it possible to let controller load and calculate everything before it displays it on the screen?
Not really... because part of Angular's philosophy is to do everything possible from the DOM, and the browser is going to see some of those before any Javascript gets executed at all.
However, Angular DOES have a standard trick to work around this. Please review the documentation for ngCloak:
https://docs.angularjs.org/api/ng/directive/ngCloak

Naming issue with AngularJS controllers

I just started playing around with AngularJS. I did however stumble upon a case that had me quite puzzled, when trying to use the angular bootstrap directives for creating tabbed panes. I followed this example, and the only thing I changed was renaming the TabsCtrl variable to TabsController, because I had been using *Controller convention in the rest of my application.
What I found really strange is that this renaming broke the entire thing! The TabsController function was never executed after the renaming. You can test it yourself on the plunker link.
I need to get this straight, as it seems scary that renaming an object like this would make it break without me knowing why. Is the *Controller variable name reserved somehow? How come I have been able to use the *Controller naming convention for the rest of my controllers without problems?
Edit: It seems that it is the exact word TabsController that is causing the issue. I tried naming it BajsController instead, and that worked..
Oh, I found it.
It seems that the bootstrap angular directives are already defining a controller called "TabsController", so that is where the conflict is.
I didn't find this conflict when I was looking for an existing object called "TabsController" in the debug console, but that is of course because it was not declared as a global variable inside the bootstrap directive.

Categories

Resources