1

I added an onblur event to all input fields, and I want to get the $scope and $element when the onblur event runs. But when I use this.$element to get the element, I get undefined.

When I log only this, I get the input tag. How can I get the $scope and $element on an onblur event?

Code:

constructor($document, $element, $scope) {
   this.$document = $document;
   this.$element = $element;
   this.$scope= $scope;
}

FunCall() {
  const formElements = this.$element[0].querySelectorAll('input');
  const watchElement = angular.element(formElements[0]);
  console.log(this);

  watchElement[0].onblur = function() {
    console.log(this); // html input element
    console.log(this.$scope); // undefined
    console.log(this.$element); // undefined
  };
}

On the first log I get the correct this, which is the controller. On the second log, inside the onblur event I get the HTML element and get undefined for the $scope and $element. How can I get the controller, like the first one inside the onblur event?

And I want to run a function inside the onblur event, but this didn't work:

watchElement[0].onblur = function() {
    this.runSecondFunction();
};

runSecondFunction() {
 console.log('test 2nd function');
}
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Can
  • 553
  • 1
  • 9
  • 29

1 Answers1

1

function() in javascript is also a constructor. This why, you can create an object by new. For example:

function ImAFunctionButCanBeConstructor() {
  this.foo = 'bar';
  this.print = function() {
    console.log(this.foo);
  }
}

const myObj = new ImAFunctionButCanBeConstructor();
myObj.print();

In a case of an event handler this is referring to the DOM element.

In order to avoid this (only if you don't need that reference), you can use an arrow function instead of regular function so this will refer to the enclosing context, which is the instance of the class.

class MyComp {
  constructor($document, $element, $scope) {
    this.$document = $document;
    this.$element = $element;
    this.$scope = $scope;

    this.FunCall();
  }

  FunCall() {
    const formElements = this.$element[0].querySelectorAll("input");
    const watchElement = angular.element(formElements[0]);
    //console.log(this);

    watchElement[0].onblur = () => {
      //console.log(this);
      //console.log(this.$scope);
      console.log(this.$element);
    };
  }
}

angular.module("app", []).component("myComp", {
  controller: MyComp,
  template: `
      <input type="text" placeholder="watch me blur" />
    `
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div id="app" ng-app="app">
  <my-comp></my-comp>
</div>

https://codesandbox.io/s/musing-moore-kohg8?file=/src/index.js

Just has to mention There are more ways to do the same.


References

https://stackoverflow.com/a/1963370/863110

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135