0

How can I pass the value of an <input type='email'> using angularjs. I need to validate the email address on the input of my form and need to generate a key with this. The only thing I need to know is how should I get the value from the input.

angular.module('myApp', [])
  .controller('EmailController', function($scope) {
    $scope.hash = "";
    $scope.generateKey = function () {
      var resultKey = $scope.email;
      // TODO: generate key
      
      // Assing value to hash
      $scope.hash = resultKey;
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="EmailController">
  <form>
    <p>Email:&nbsp;<input type="email" ng-model="email" ng-keyup="generateKey()"></p>
    <p><b>Hash:&nbsp;</b>{{hash}}</p>
  </form>
</div>

Edit 1

I could use <input type='text'> and validate with a regex but I want to use type='email' as in the cellphone display more options on the keyboard. Does exist a way to get the input value using angular even if it isn't a valid email?

4
  • $scope.email should have the value of the input field. Commented Jun 14, 2017 at 15:50
  • Well, it doesn't @PrerakSola Commented Jun 14, 2017 at 15:53
  • 2
    You need to enter a valid email address. Here's a fiddle of your exact code. It works completely fine. jsfiddle.net/prerak6962/vh6vgxw8 Commented Jun 14, 2017 at 15:57
  • @PrerakSola, thanks but thats my issue. I added more information to my post. Commented Jun 14, 2017 at 17:32

2 Answers 2

2

Use ng-model-options="{ allowInvalid: true }" if you want invalid email addresses to be bound to your controller:

<input type="email" ng-model="email" ng-keyup="generateKey()" ng-model-options="{ allowInvalid: true }">

Edit: You usually shouldn't data-bind to a primitive because prototypal inheritance can sometimes lead to binding to the wrong scope. Try binding to an object instead, like data.email.

Edit: Live example

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

6 Comments

Well, that doesn't changes the fact that when I start to wrtie something like: fdsfds I can't see the output.
You can't? I played around with the jsfiddle provided in the comments and added my solution and it works. Perhaps you have a problem data-binding to the wrong scope. Try binding to an object like data.email instead.
Paste the url here @Frank. I did and didn't workd, sorry for change Accept Answer without testing. When I tested rigth now it didn't work. Also I added more info to my question.
By the way, you may want to use ng-change instead of ng-keyup. It will run right after the model is updated.
add the link to your answer. If anoyone have the same problem can fix it, I don't understand why it didn't work when I did
|
1

The way angular handles input values and validations is via $parsers. you can intercept the default parsers and therefore get the value before it get to the email validation. Created this little snippet to further illustrate my point. Notice that I am not using .push to add my parser but instead I am using .unshift. I use unshift rather than push because I want to make sure my parser is the first on the list. or at least, the first at the moment i added to the list. This will guarantee that it runs before the default parsers which are already in the list by the time my code runs.

var app = angular.module('myApp', []);
    app.controller('EmailController', function($scope) {
      $scope.hash = "";
    });
    app.directive('generateKey', function(){
      return {
        require: ['ngModel'],
        link: function(scope, element, attr, ctrls){
          var ngModel = ctrls[0];

          ngModel.$parsers.unshift(function(text){
            scope.hash = text;
            return text;
          });
        }
      };
  });

for a complete snippet, please visit: https://jsbin.com/vabofapigo/edit?html,js,output

4 Comments

Be careful with this solution. It will write to whatever hash variable is in the current scope. So if you use this inside ng-repeat or ng-if it will break.
Yes! that is true. However, two things rise up from truth: 1. Why would you have duplicate variables attached to the scope? 2. if needed be, the directive scope can be isolated and have the hash variable passed down manually when adding the directive to the element. Thoughts? @FrankModica
1. I'm saying that if you start out with only one hash on the controller scope, directives like ng-if create scopes that inherit from the parent scope (using scope: true). So your generateKey directive will initially read hash from the controller, but will write hash to its own scope (the one created by ng-if), creating a duplicate and breaking binding. 2. Yes, adding scope: { hash: "=" } to generateKey and passing in the hash is better: <input ng-model="theEmail" generate-key hash="hash">
Note that even doing #2 in the above comment may not work if ng-if is present, because in general you should bind to objects instead of primitives to prevent binding issues due to prototypal inheritance: <input ng-model="data.theEmail" generate-key hash="data.hash">. This would not be an issue with your directive of course. It's just how binding works.

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.