1

I am building a sign in form using Angular and am also using a Chrome extension called Password Hasher Plus. The extension works by replacing the data in the password input field with the a hashed version of the password.

The problem is that the model is not updating when the Chrome extension injects the new data into the password field.

When I have searched for similar problems I have seen the suggestion of using $scope.$apply() as a solution. As far as I can tell though $scope.$apply() must be passed the code that is changing things. Am I correct in that understanding? In this case I don't have access to the code since it is in the extension.

The more general problem here is how do you update the scope when external javascript you have no control over is manipulating the DOM?

My problem is demonstrated in the following example code.

Example view

 <body ng-controller="MainCtrl">
    <input ng-model="password" type="password" name="password"/><br><br>
    <button type="submit" value="Submit" ng-click="submit()">
     Submit
    </button><br><br>
    <span>DOM Value: {{domValue}}</span><br>
    <span>Scope Value: {{scopeValue}}</span>
  </body>

Example controller

app.controller('MainCtrl', function($scope) {

  $scope.submit = function(){
    $scope.domValue = document.getElementsByName("password")[0].value;
    $scope.scopeValue = $scope.password;
  };

});

This example can be seen in this Plunker. to get it to work you will have to install the Chrome extension mentioned above. After typing something into the password field, clicking the extension hash button then clicking the submit button you can see the DOM value and the scope value are different.

thinktt
  • 363
  • 2
  • 13
  • This reminds me of a similar issue of getting notified when the browser auto-fills a login form. You might give this a try. http://stackoverflow.com/questions/14965968/angularjs-browser-autofill-workaround-by-using-a-directive/25687396#25687396 – Bernard Oct 14 '14 at 03:02
  • Thank you Bernard, I am looking into this right now. – thinktt Oct 15 '14 at 01:33

1 Answers1

1

The link Bernard posted is the correct solution to this problem.

Apparently this is an Angular issue, although one that may not be officially fixed for various reasons. However one of the Google Angular developers has written a fix that solves this auto fill problem. Using this polyfill worked perfectly and is probably the best solution since it is built by an actual Angular developer.

I did not want to add that much extra weight to my code though so I used this solutions, snagged from the same thread.

This Directive:

app.directive("autofill", function () {
return {
    require: "ngModel",
    link: function (scope, element, attrs, ngModel) {
        scope.$on("autofill-update", function() {
            ngModel.$setViewValue(element.val());
        });
     }
   };
});

Then this line in the controller:

$scope.$broadcast("autofill-update");

If you have a similar problem consider using one of these solutions or visiting the other SO thread to learn more.

Community
  • 1
  • 1
thinktt
  • 363
  • 2
  • 13