The significance of 'this' in an Angular controller

Forgive me for what may seem like a silly question, but I believe it will help clarify my understanding.

Let's dive into JavaScript:

  var firstName = "Peter",
    lastName = "Ally";

    function showFullName () {
    // The "this" inside this function refers to the window object
    // since showFullName() is in the global scope, just like firstName and lastName
    console.log (this.firstName + " " + this.lastName);
    }

    var person = {
    firstName   :"Penelope",
    lastName    :"Barrymore",
    showFullName:function () {
    // The "this" below points to the person object, as shown by person invoking the function.
    console.log (this.firstName + " " + this.lastName);
    }
    }

    showFullName(); // Peter Ally​
​
    window.showFullName(); // Peter Ally​

This makes sense to me. Now, transitioning to an Angular controller:

<script>
var app = angular.module("myApp", []);
console.log("Before Controller",this);
app.controller("myCtrl", function($scope) {
    console.log(this);
    $scope.firstName = "John";
    $scope.lastName = "Doe";
    this.myTestFunction = function(){
        return this;
    }

    console.log("In test function ",this.myTestFunction());
});
</script>

Shouldn't the second line still log window because the controller function is in the global scope (I think)?

However, it returns an Object. Why?

Can I use this.myTestFunction without using ControllerAs syntax? What sets them apart?

Why does the last line also log object (in myTestFunction) when I am simply returning this from within?

I'm a bit confused about all of this. Could someone break it down simply?

Before Controller Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
VM2143 tryit.asp?filename=try_ng_module:5 Object {}
VM2408 tryit.asp?filename=try_ng_module:12 In test function  Object {myTestFunction: function}

Answer №1

When the last console log displays object object, it means you are attempting to concatenate an object with a string. To resolve this, remove the string and only show the function response.

console.log(this.myTestFunction());

Regarding the second question, you cannot access this.myTestFunction in HTML without utilizing the controller as a function. Without it, Angular can only recognize the scope functions within the controller.

var app = angular.module("myApp", []);
console.log("Before Controller",this);
app.controller("myCtrl", function($scope) {
    console.log(this);
    $scope.firstName = "John";
    $scope.lastName = "Doe";
    this.myTestFunction = function(){
        return this;
    }

    console.log("In test function ",this.myTestFunction());
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
 
</div>

Answer №2

Why does the second line still log window right when the controller function is defined in the global scope? However, it returns an Object. What is the reason for this?

In AngularJs Controllers, Services, Factories, etc., the this keyword refers to your controller/module itself. When a Module Constructor is called, this represents the module itself. In essence, this on a Controller is an Object that contains all of the controller's functions and variables. If a Controller named MyController is associated with a view MyView.html, then only that specific view can access MyController's variables and functions.

Can I use this.myTestFunction without using ControllerAs syntax? What is the difference between the two?

No, you cannot use this without utilizing the ControllerAs syntax. For example:

angular.module('myApp')
       .controller('MyController', MyController);

function MyController(){
   var vm = this;
   vm.hello = 'Hello There!';
}

And

<body ng-controller="MyController as myCtrl">
  <p>{{myCtrl.hello}}</p>
</body>

It will display Hello There!.

Why does the last line also log object (In myTestFunction) even though I am simply returning this from within?

This occurs because, as mentioned earlier, this is an object that contains all the variables and functions created inside the controller itself.

Additional Info:

It is recommended to use this instead of $scope within your controller. One of the reasons for this is that when you define a function using this, you can be sure that this specific function is accessible to a given view or module. Check out Angular Style Guide by John Papa on Controllers for more details.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it necessary to have required isolated scope attributes in AngularJS Directives?

I'm diving into Angular for the first time and trying to build a directive. I have a question about isolated scope attributes. Say I have this directive: MyApp.directive('myDirective', function() { return { scope: { ...

Is there a way to automatically send users to a different PHP file once they click "submit"?

I need to redirect to a different php file named index2.php. The username and password values are already set as follows: Username=sid, Password=yeaoklogin. When the user clicks on the Login button, they should be redirected to a page called index2.php. ...

Using checkboxes to select all in AngularJS

Recently, I started working with Angularjs and came across some legacy code. I am trying to figure out a way to select all checkboxes once the parent checkbox is selected. Here is the parent checkbox: <div class="form-group"> <label for="test ...

What is the method to turn off readonly property for input fields in Laravel?

I'm encountering an issue with my Laravel project. I have a form with an input field that has the readonly attribute set. <input type="text" name="anamFam" id="anamFam" value="{{$aFam->anam_cont}}" readonly> When I click the edit button, I ...

Ensuring the timely execution of Javascript functions with Selenium before moving on

While working on creating test cases using Selenium, I encountered an issue. In one of my test cases, there is a small form and a search button on the website I'm testing. Filling the form and clicking the button are not the problem. The issue arises ...

Modifying information in a single array in Vue JS has a ripple effect on

I'm really struggling to understand what the ... want with this Vue component! Can someone please help me out? Here is my code: var groupadding = new Vue({ el: '#groupAdd', data:{ currentFullData: [], localData: [] }, method ...

When making a delete request from an Angular application to an ASP.NET Core API using $http.delete, an unsupported media type error

I keep encountering a 415 HTTP error response when attempting to send a request to an aspnetcore API. Interestingly, this issue does not arise if I switch the endpoint from [HttpDelete] to [HttpPost]. Here's a snippet of the controller in the aspnetc ...

Exploring the possibilities with Node.js and OpenCV

I'm experiencing difficulties with face tracking and detection using the npm opencv package. Right now, I'm attempting to draw a circle around each detected face. Below are the error details and associated files. I'm unsure if it's a b ...

swap between style sheets glitching

My website features two stylesheets, one for day mode and one for night mode. There is an image on the site that triggers a function with an onclick event to switch between the two stylesheets. However, when new visitors click the button for the first ti ...

Troubleshooting jQuery: Unable to refresh the webpage

I have a PHP page that contains a form, checkboxes, and a submit button. I added an if statement to execute a PHP script I created when the button is clicked, which deletes certain values from the selected rows. The button functions properly and changes s ...

Transmitting an Array of Objects to a Web API using AngularJS

Throughout this process, I retrieve an array of "vehicles" from the Web API. I then make modifications and perform various actions on each vehicle. Afterwards, I aim to send back the updated list without the need for looping through it again. I have exper ...

Node.js schedule randomizer

I'm trying to figure out how to call a function within a random range of time intervals in Node.js. What I need is for the function to run once between 2 and 12 hours, then again at another random interval between 2 and 12 hours, and so on. However, I ...

Inject a jQuery form submission using .html() into a div element

I am currently working on developing a basic forum where users can view listed topics and have the option to add new ones on-the-fly by clicking a link or image. How can I detect and handle the form submission event for the dynamically added form within an ...

The error message "Uncaught ReferenceError: require is not defined" is commonly encountered when using Webpack

Despite countless similar questions, none have provided a solution to my issue because the underlying problem seems to elude me. I am attempting to bundle files for the browser using webpack 4.26.1, but no matter what I try, I consistently encounter the er ...

invalid audio element

I'm currently working on building an audio player with a visualizer feature. However, when I try to initiate the audio player by clicking on the input button, my debug console keeps showing this error message: Uncaught (in promise) DOMException: Fa ...

What is the best way to introduce a time delay between two JavaScript functions?

Here is some JavaScript code that I am working with: clientData.reloadTable( "CreateCSV", "/create/file" ); $("#downloadFrame").attr("src","/download/download"); The first statement in the code above creates a CSV file on the disk. The second statement d ...

Position an element with absolute positioning to the right edge of a relative element

I have a situation where I need to align the end of a position absolute element with the end of a relative element, but the relative element's width is not fixed and may vary based on content. This scenario arises as I am creating a custom dropdown m ...

How do I incorporate a standalone checkbox in a React Material-UI table without affecting row selection upon clicking?

I would like to have a distinction between clicking on a checkbox and clicking on a row. Specifically, I want the following behavior: when I click on the checkbox, only the checkbox should be checked; and when I click on the row, only the row should be se ...

How to enable Autocomplete popper to expand beyond the menu boundaries in Material UI

Within my Menu component, I have an Autocomplete element. When the Autocomplete is clicked, the dropdown list/Popper appears but it's confined within the Menu parent. How can I make it so that the Autocomplete's dropdown list/Popper isn't re ...

Image caption dynamically updated to match thumbnail caption using jQuery upon click event

My goal is to dynamically load the data-caption of thumbnail images when clicked, and then update the main image's data-caption when the main image is changed with a thumb image. I am currently struggling to make the data-caption update along with the ...