Understanding the 'this' keyword in Angular's 'controller as' syntax

Within my parent controller, UserEditCtrl, I am trying to access a user object from a service and set a property to another variable in the child controller, EditUserCtrl:

userMgmtSvc.user(scope.editUserId).then(function(data) {
  this.user = data;
});

However, when attempting to assign this property, an error is thrown:

Cannot read property 'user' of undefined.

I am struggling with referencing objects that are set using this. For example, trying to log the user object returns undefined:

console.log('user', this.user);

Here is a portion of the parent controller code:

(
  function (app) {
    'use strict';

    app.controller('UserEditCtrl', ['$scope', '$http', 'userMgmtSvc', 'createUserSvc', 'authSvc', '$state', '$timeout', '$location', '_',
      function (scope, http, userMgmtSvc, createUserSvc, authSvc, state, timeout, location, _) {

      userMgmtSvc.user(scope.editUserId.id || sessionStorage.getItem('editUser')).then(function(data) {
        this.user = data;

        createUserSvc.states().then(function(data) {
          this.states = data;
        });

        createUserSvc.countries().then(function(data) {
          this.countries = data;
        });

        createUserSvc.roles().then(function(data) {
          this.roles = data;
        });

        createUserSvc.insuranceGroups().then(function(data) {
          this.insuranceGroups = data;
        });

        this.selectedRoles = this.user.roles;
      });
 }]);

}(window.app)
);

Answer №1

One common error that often occurs is referencing the current context with this inside a callback without knowing the execution context, leading to values being set in unexpected places.

To avoid this issue, it's recommended to assign the controller instance's context to a variable when the controller starts and use that variable for all assignments instead of assuming what this refers to.

 .controller('crtl',[deps..., function(...) {
       //Set this
       var vm = this; //Always use this cached variable have seen a commonly used name of vm

       //............... 
       //...............
       userMgmtSvc.user(scope.editUserId).then(function(data) {
         vm.user = data;
       });

       //...............
       vm.selectedRoles = vm.user.roles

   }

There are various other methods to handle this situation such as using angular.bind or es5 function.bind to create pre-bound functions (functions with specified context already bound), but using a cached context is the simplest approach.

If you're working with TypeScript, you can utilize the => (fat arrow) syntax since TypeScript in ES5 mode will convert this correctly.

      userMgmtSvc.user(scope.editUserId).then((data) => {
         this.user = data;
      });

could be rewritten as:-

    var _that = this;
    userMgmtSvc.user(scope.editUserId).then((data) => {
         _that.user = data;
     });

Arrow functions will become part of the language itself under the ES6 specifications once the engines start supporting the arrow function syntax. So with ES6, you can safely write:-

      userMgmtSvc.user(scope.editUserId).then((data) => {
         this.user = data;
      });

This resource offers an excellent explanation on handling this within callbacks

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

Issue with Jade not displaying external JSON data

I am struggling with a jade template that is supposed to display all possible solutions from the QPX Express search request: { kind: 'qpxExpress#tripsSearch', trips: { kind: 'qpxexpress#tripOptions', requestId: 'RwDOf6H ...

Attempting to retrieve the value from `document.all["" + object.getAttribute("EndDate", true) + ""].value;` is ineffective in Firefox

In Firefox, document.all["" + object.getAttribute("EndDate", true) + ""].value; works but not in IE. Is there an alternative method that can work across different browsers? ...

Switch between 2 sections with a click of a button (Implementing Javascript, HTML, and CSS)

There are two divs with different content inside, and I want to toggle between them using a button. Here are my two divs with classes "step1Content" and "step2Content" respectively. <div class='step1Content'> Content1 </div> <div ...

Utilizing AngularJS: Conditionally rendering ngIf within an array of objects containing unique properties

Facing a challenge with the ngIf directive that I have been struggling to resolve despite trying various solutions. In my scenario, I have an array of objects, each containing different properties. The structure is as follows: object = [ { ...

Troubleshooting problem with ng-repeat in AngularJS - attempting to incorporate a new function into the $

Utilizing AJAX to retrieve data from a JSON file, inserting it into the controller $scope, and then employing it in ng-repeat has been successful. However, issues arise when attempting to incorporate a function into the $scope to execute another task. ...

What steps can be taken to avoid a nodejs server from crashing due to unexpected data?

While I have a wealth of experience working with servers like nginx, apache, and jboss, I am relatively new to nodejs server (I was drawn in by its socket.io features). What puzzles me is that seemingly insignificant issues such as accessing object.MyPrope ...

Is it possible to access static files outside the root directory using express.js?

I currently have an Express app set up to act as a proxy for certain requests originating from an Angular app. The Angular app is already built with a configuration that I do not want to change. My goal is to organize my Angular and Express apps in separa ...

What role does the index number play in MongoDB/Mongoose and why is it important?

When using mongoose with Mongo DB, this is how I set up indexes: UserSchema.index({ email: 1, username: 1 }, {unique: true}); Initially, I only had the email field indexed. However, since usernames must also be unique and I need to check if a username ...

Dynamically update a directive array in Vue.js based on real-time changes

In my Vue project, I have an array defined in the data() method that is populated through a custom directive in its bind hook. Here's the code snippet: import Vue from 'vue' export default { el: '#showingFilters', name: "Filte ...

What tips can you provide for shrinking the size of an AngularJS website with the help of Google Closure Compiler?

Is there a way to decrease the size of an Angularjs site using Google Closure Compiler? I have a website built on Angularjs 1.8.x and I am interested in compiling it with Closure. Are there any examples or demonstrations available to help me achieve this ...

Struggling to navigate to another page using Vue Router?

I'm currently in the process of integrating Vue Router into one of my projects to enable navigation between different pages. Since I'm not very familiar with Vue Router, there's a chance I may have made a mistake in the setup. import {creat ...

Is it possible to run TypeScript-transpiled code in a browser directly with es6-style classes and import statements without the need for an extra transpilation

When I transpile TypeScript code using target:"es5" for es6-style classes and React, the resulting transpiled code in my intended entry point (in this case a file named App.ts) looks something like this: Object.defineProperty(exports, "__esM ...

The functionality of OnMouseOver event within CKEditor

I prefer using the CKEditor WYSIWYG editor. One issue I have encountered is with a div element that includes an onMouseOver attribute. When this element is within the editor, the onMouseOver attribute gets changed to data-cke-pa-onmouseover. Despite my eff ...

A role requiring coordinates x, y, and z with significant values

http://jsfiddle.net/eho5g2go/ var offset=10000000; ... camera.position.set(offset,offset,400); mesh.position.set(offset-300,offset,0); camera.lookAt(mesh.position); ... animate(); The "offset" variable is crucial for determining the camera and mesh p ...

Image-switching button

I'm new to JavaScript and struggling with my first code. I've been staring at it for two days now, but can't figure out what's wrong. The goal is to create an HTML page where the user can change an image by clicking on a button, and th ...

React App stalled due to continuously running function

In this section of my React app, the createBubbles function is functioning properly. However, I am encountering an issue where the entire app freezes when navigating to another page after visiting this one. The console displays the following errors and de ...

Encountered an issue while attempting to retrieve the access token from Azure using JavaScript, as the response data could

Seeking an Access token for my registered application on Azure, I decided to write some code to interact with the REST API. Here is the code snippet: <html> <head> <title>Test</title> <script src="https://ajax.google ...

The code inside the if statement is somehow executing even when the if statement is not true

Similar Question: Issue with jQuery function running at inappropriate times I've spent several hours trying to figure out why my function isn't working properly. I have a function inside an if ($window.width() < 1000) statement, but it se ...

Get a URL from the JSON data returned by the Wikipedia API

How can I retrieve the image URL from a JSON response and store it in a variable? I found helpful information on the MediaWiki API help page Following this example to extract image information from a page: https://commons.wikimedia.org/w/api.php?action= ...

Find and delete an item from a JSON array

Currently, I am attempting to locate a specific object within a JSON array and remove it. The structure of my JSON array containing objects is as follows: var data = [{ {id: "1", name: "Snatch", type: "crime"}, {id: "2", name: "Witches of Eastwic ...