title: How to create a directive in Angular to mask us phone number without changing model?
body: <p>I have a directive in Angular Js that masks phone numbers to US format (xxx) xxx-xxxx ,</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const myApp = angular.module("myApp", []);
  
  myApp.controller("MyCtrl", function ($scope) {
    $scope.validateModel = function name(params) {
    };
  });
  
  // Excercise 1
  myApp.directive("canadaPhone", function ($filter, $browser) {
    return {
      require: "ngModel",
      link: function ($scope, $element, $attrs, ngModelCtrl) {
        const listener = function () {
          var value = $element.val().replace(/[^0-9]/g, "");
          $element.val($filter("tel")(value, false));
        };
  
        // This runs when we update the text field
        ngModelCtrl.$parsers.push(function (viewValue) {
          return viewValue.replace(/[^0-9]/g, "").slice(0, 10);
        });
  
        // This runs when the model gets updated on the scope directly and keeps our view in sync
        ngModelCtrl.$render = () =&gt; {
          $element.val($filter("tel")(ngModelCtrl.$viewValue, false));
        };
  
        $element.bind("change", listener);
        $element.bind("keydown", (event) =&gt; {
          const key = event.keyCode;
          // If the keys include the CTRL, SHIFT, ALT, or META keys, or the arrow keys, do nothing.
          // This lets us support copy and paste too
          if (key == 91 || (15 &lt; key &amp;&amp; key &lt; 19) || (37 &lt;= key &amp;&amp; key &lt;= 40)) {
            return;
          }
          $browser.defer(listener); // Have to do this or changes don't get picked up properly
        });
  
        $element.bind("paste cut", () =&gt; {
          $browser.defer(listener);
        });
      },
    };
  });
  myApp.filter("tel", function () {
    return function (tel) {
      if (!tel) {
        return "";
      }
  
      let value = tel.toString().trim().replace(/^\+/, "");
  
      if (value.match(/[^0-9]/)) {
        return tel;
      }
  
      let city, number;
  
      switch (value.length) {
        case 1:
        case 2:
        case 3:
          city = value;
          break;
  
        default:
          city = value.slice(0, 3);
          number = value.slice(3);
      }
  
      if (number) {
        if (number.length &gt; 3) {
          number = number.slice(0, 3) + "-" + number.slice(3, 7);
        } else {
          number = number;
        }
  
        return ("(" + city + ") " + number).trim();
      } else {
        if (city) {
          return "(" + city;
        } else {
          return "";
        }
      }
    };
  });
  
  // Excercise 2</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!doctype html&gt;
  &lt;html lang="en"&gt;
  
  &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;title&gt;SurexApp&lt;/title&gt;
    &lt;base href="/"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
    &lt;link rel="icon" type="image/x-icon" href="favicon.ico"&gt;
      &lt;script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"&gt;&lt;/script&gt;
    &lt;!-- CSS only --&gt;
    &lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
      integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous"&gt;
  
  
  &lt;/head&gt;
  
  &lt;body&gt;
  
    &lt;!-- Angular JS --&gt;
    &lt;div ng-app="myApp" ng-controller="MyCtrl"&gt;
  
      &lt;div class="container app-container"&gt;
        &lt;!-- &lt;h1&gt; Angular Js Excercises&lt;/h1&gt; --&gt;
  
  
        &lt;!-- Excercise 1 --&gt;
        &lt;div&gt;
          &lt;label for="excercise1"&gt;Angular Js Excercise 1&lt;/label&gt;
          &lt;input type="text" ng-model="phone" id="excercise1" placeholder="(987) 654-3210" ng-change="validateModel()" canada-phone&gt;
          &lt;div&gt; Model: {{phone}}&lt;/div&gt;
        &lt;/div&gt;
  
  
      &lt;/div&gt;
  
  
    &lt;/div&gt;
  
    &lt;app-root&gt;&lt;/app-root&gt;
  
  
  &lt;/body&gt;
  
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>How can I recreate the same directive in Angular ( typescript ) ?</p>
  <p>I created a directive from another post but It alters the model too,
  My Requirement is that it should visually show as (xxx) xxx-xxxx, but the model value should not be changed i.e. it should be xxxxxxxxxx</p>
  <p>My Stackblitz demo -&gt; <a href="https://stackblitz.com/edit/angular6-phone-mask-7tglv9?file=app%2Fapp.component.html" rel="nofollow noreferrer">https://stackblitz.com/edit/angular6-phone-mask-7tglv9?file=app%2Fapp.component.html</a></p>