ng-cloak directive gets removed too early

Problem

I have an angular-js app with some controllers that shouldn't be shown initially. They flash on the screen despite my use of ng-cloak. The problem seems to be that compile gets called and removes the ng-cloak directives and class, this makes the controllers contents visible even though it shouldn't be because ng-show is false.

If I pause js execution in ng-cloak's compile method I can see the elements appear as the ng-cloak directive is removed. If I pause js execution in the controller (for example on "$scope.visible = false;") I can see the controller stays visible on the page. The controller is then invisible again as it should be sometime later in loading.

  • I am loading my app.js and angular.js in the document HEAD
  • I have my css in the document HEAD
  • I have included the ng-cloak css rule with "!important" in my external css and inline

How can I prevent this flashing? Why doesn't ng-cloak pay respect to ng-show?

index.html:

<div ng-cloak class="ng-cloak" ng-controller="RoomsController" ng-show="visible">
    <h1>This flashes, it can be seen if we set a breakpoint in the controller js, or after the ng-cloak directive's compile method in angular.js</h1>
</div>

app.js:

app.controller('RoomsController', ['$scope',
    function ($scope) {
        $scope.visible = false;
    }
]);
Problem courtesy of: Salami

Solution

I've reproduced your issue and the thing that worked for me was to create inner div and use ng-if directive instead of ng-show. I hope it helps.

<div data-ng-controller="RoomsController">
    <div ng-cloak class="ng-cloak" data-ng-if="visible" >
        Some text
    </div>        
</div>
Solution courtesy of: Łukasz Wiatrak

Discussion

I had a similar problem with ngCloak in IE mobile. The simplest solution I came up with is similar to some of the other answers, but I use ng-show instead, and without any extra $scope variables:

<div class="ng-hide" ng-show="true">
  {{mydata}}
</div>

The solution requires that you add the ng-hide class and ng-show="true". This ensures that the element will only be visible after the ng-show directive is linked.

Discussion courtesy of: Gil Birman

ngCloak directive hides the related elements until the end compile process. This is useful for hiding {{ someBinding }} stuff, and probably nothing else. The actual linking and binding in the linking process.

To prevent flashing of an element, it shouldn't be there until the application bootstraps itself. You can take a look at ngInclude for simple widgets, and ngView for bigger, complex things.

Discussion courtesy of: Umur Kontacı

After a lot messing around I managed to "fix" this by adding ng-hide class to the element, while removing ng-cloak completely:

<div class="ng-hide" ng-controller="RoomsController" ng-show="visible">
    <h1>This flashes, it can be seen if we set a breakpoint in the controller js, or after the ng-cloak directive's compile method in angular.js</h1>
</div>

This hides the element initially. Angular then removes the ng-hide class when processing the ng-show directive.

Discussion courtesy of: vit

use a ng-hide in the class, JS will take it off or set it again even if its there but till JS kicks in it can sit there and use CSS to hide your div

<div data-ng-controller="RoomsController">
    <div ng-cloak class="ng-cloak ng-hide" data-ng-if="visible" >
        Some text
    </div>        
</div>
Discussion courtesy of: Theluckin

This recipe can be found in it's original form on Stack Over Flow.