2

Accessing scope in a link function within a directive is "undefined" following minification for a number of examples (using Closure Compiler) but works fine pre-minification.

For example, code below from the Angular tutorial with some alterations. After minification $scope.format is not picked up by the directive at any point. The directive shows the default format (Jul 15, 2015) without any errors. Prior to minification, the directive displays format as defined in $scope.format (7/15/2015 12:09:04 AM).

app.js

.controller('Controller', ['$scope', function ($scope) {
    $scope.format = 'M/d/yy h:mm:ss a';
}])
.directive('myCurrentTime', bd.myCurrentTime.Directive.factory)

myCurrentTime-directive.js

'use strict';

goog.provide('bd.myCurrentTime.Directive.factory');

/**
 * Example directive factory.
 * 
 * @return {Object}
 * @ngInject
 * @export
 */
bd.myCurrentTime.Directive.factory = function ($interval, dateFilter) {
    function link(scope, element, attrs) {
        var format,
        timeoutId;

        function updateTime() {
            element.text(dateFilter(new Date(), format));
        }

        scope.$watch(attrs.myCurrentTime, function (value) {
            format = value;
            updateTime();
        });

        element.on('$destroy', function () {
            $interval.cancel(timeoutId);
        });

        // start the UI update process; save the timeoutId for canceling
        timeoutId = $interval(function () {
            updateTime(); // update DOM
        }, 1000);
    }

    return {
        link: link
    };
};
// Added by ng-annotate
bd.myCurrentTime.Directive.factory.$inject = ["$interval", "dateFilter"];

html file:

<div ng-controller="Controller">
    Date format: <input ng-model="format"> <hr />
    Current time is: <span my-current-time="format"></span>
</div>
6
  • 1
    can you provide plunkr for minified and nonminified variant? Commented Jul 14, 2015 at 14:11
  • What library do you use for minification? Commented Jul 14, 2015 at 14:33
  • @tomepejo First sentence, he's using Google's Closure compiler. Commented Jul 14, 2015 at 15:09
  • @Agop, methinks in advanced mode, Google's Closure compiler can not minify $scope.format to $scope.f but delete it because it not used in function Commented Jul 14, 2015 at 15:13
  • @Grundy Yeah, that might be possible too. That's why we need to see the minified code. Either way, using the string export should help, based on what we have to work with so far. Commented Jul 14, 2015 at 15:50

1 Answer 1

2

Are you using the Closure compiler's Advanced Compilation mode? Without seeing your minified code it's hard to pinpoint the problem, but here are some ideas:

  1. In this part of your code:

    .controller('Controller', ['$scope', function ($scope) {
      $scope.format = 'M/d/yy h:mm:ss a';
    }])
    

    $scope.format might be renamed to something like s.f. Normally, this wouldn't be a problem, especially since $scope is injected properly. However, you're referencing the format property in the HTML, which the Closure compiler doesn't know about:

    Date format: <input ng-model="format"> <hr />
    Current time is: <span my-current-time="format"></span>
    

    Try using $scope['format'] = 'M/d/yy h:mm:ss a' instead - the Closure compiler never changes strings, so this should export the correct property name for the HTML. Now, remember - once you use a string to access a property, always use a string to access that property.

  2. Similar to #1, attrs.myCurrentTime might be renamed to something like a.m. Try using a string property name (attrs['myCurrentTime']) to ensure that the compiled JavaScript matches the HTML properly.

Again, these are just ideas at this point. If you post the minified code as a full example, we'll be able to help more.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for this. That makes far more sense now. Idea 1 does not make a difference (as the minified code still has x.format in it). However, idea 2 fixed the issue and also fixed the issue in the more complicated application I'm writing. Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.