Losing scope of "this" when accessing an Angular2 app through the window

My Angular2 app has exposed certain methods to code running outside of ng2. However, the issue arises when calling these methods outside of ng2 as the context of this is different compared to when called inside.

Take a look at this link to see what exactly is happening in the console.

Initially, my app component sets the name to "Angular2" upon loading. I have a method called doSomething, which simply changes the name to "modified angular2 app". When I try to call this method using window.myVar.doSomething(), the scope of this becomes the object I exposed instead of my class. How can I access the name property? I attempted using self = this in the constructor and then changing self.name, which worked but failed during bundling and minification for production.

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
    </div>
  `,
})
export class App {
  name:string;

  constructor() {
    this.name = 'Angular2'
  }

  doSomething(){
    this.name = "modified angular2 app"
  }

  ngOnInit() {

    window.myVar = {doSomething:this.doSomething}

  }

}

In my index.html, I added a snippet to call my doSomething method.

<body>
    <my-app>
    loading...
  </my-app>
  <script>
    function checkReady() {
      if (window.myVar) {
        console.log("Ready")
        console.log(myVar)
        myVar.doSomething();
      } else {
        setTimeout(function() {
          console.log("Not ready")
          checkReady()
        }, 500)
      }
    }
    checkReady()
  </script>
  </body>

Answer №1

Make sure to call bind() on your function in order to set the correct context. By doing this, you ensure that the function will always have access to the variables declared locally.

window.myVar = { doSomething: this.doSomething.bind(this) };

Answer №2

In TypeScript, you can utilize the fat-arrow syntax to automatically bind this to the class instance:

export class App
{
  //...
  doSomething = () => {
    this.name = "updated angular2 app" 
  }
  //...
}

It's important to note that using this syntax means the function doSomething is no longer in the prototype of App.

For more information on handling this in typescript/javascript, check out this resource which discusses the pros and cons of various approaches.

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

What could be causing the reliability issue with this particular Angular JS code for dropdown menus?

Attempting to create a dynamic country-city dropdown menu using AngularJS <div> Country: </br> <select data-ng-model="country" ng-options="country.name for country in countries" data-ng-change="updateCountry(country) ...

Creating a nested set of directives by iterating over an array within an AngularJS directive

When working inside an angularJS directive, I am attempting to iterate through an array and create a nested list of directives based on the values. The current version of the directive is as follows: Type Directive .directive("type", function($compil ...

Troubleshooting the issue of the Delete Service not functioning properly within Angular

ListStore.ts file export class ListstoreComponent implements OnInit { rawlist; name = ''; id = ''; storeid = ""; store: Store; constructor(private api: APIService, private router: Router, private route: ActivatedRoute, pri ...

Looking to extract the expiration date from an x509 certificate?

I am currently engaged in a project that involves retrieving and displaying certificate information from an Azure integration account using Angular/Typescript. One of the requirements is to show the decoded public certificate to users to extract important ...

The back button on an Angular JS application should display a confirmation dialog when pressed

I am currently working on an AngularJS mobile app that consists of various modules. One of my requirements is to access the device's back button within the application, and I also need a dialog with "OK" and "Cancel" options. Clicking on "OK" should ...

The HTML checkbox remains unchanged even after the form is submitted

On a button click, I have a form that shows and hides when the close button is clicked. Inside the form, there is an HTML checkbox. When I check the checkbox, then close the form and reopen it by clicking the button again, the checkbox remains checked, whi ...

What is the best way to call an API within a loop using Node.js?

How can I efficiently make API calls based on page numbers in a loop? I am using the request() function for API calling, but when debugging my code, the response block is not reached and I do not get a response. Can someone please provide guidance on how ...

At what point is the JavaScript function expression triggered in this code snippet?

let express = require('express') let app = express(); app.use(express.static('static')); let server = app.listen(3000, function() { let port = server.address().port; console.log("The server has started on port", port); }); I ...

Disable the scroll bar on a bootstrap modal

<span class="education"style="font-size:170%;line-height:150%;">&nbsp;Education <br> <small style=" color:gray;font-size:60%;">&nbsp; Blue Ridge University,2012-2014 </small> <br> <sma ...

Delete an <li> element upon clicking a span tag

I've been attempting to fadeOut some <li> elements, however I haven't had any success. Here's my code below: <li class="lclass" id="1"> First Li <span class="removeit" id="1" style="color:#C00;">Remove</span> ...

How can one effectively handle elements or objects that are both event listeners and event triggers?

Yesterday, I posted a similar question but found it too complex and vague after further research, so I removed it. I have now created a new demo here, which should be self-explanatory for the most part. Below are the HTML and JavaScript sections: <sel ...

What is the best way to confirm that a certain element is not present on the page using playwright?

My current challenge involves testing a website that features a logo, and I need to ensure that the logo does not display on specific pages. I have been exploring the Playwright assertions documentation for guidance on how to assert that an element does N ...

Information is being received, but unfortunately, it cannot be displayed

Currently, I am experimenting with using the axios http request to showcase some data. My focus is on exploring how to exhibit api data on the client side with react. If you are interested in seeing my progress so far, feel free to check out the link belo ...

Selection box and interactive buttons similar to those found in Gmail

Looking to achieve these effects for <option> and <button> using CSS and JavaScript. Any suggestions on how to do this? ...

Obtain a numerical output from a selection of numbers

I am facing a simple problem that I can't solve due to my lack of knowledge and have not been able to find any solution online. What I want to achieve is: Create a "value 1" from an array of integers. Generate a random "value 2". Check if the rando ...

Best practices for resolving classlist.toggle issues with my dark mode button

The code seems to work only the first time, but after activating light mode again, the sun stops appearing. How can I ensure that the 'bi-sun' class is added back every other click or when dark mode is not activated? function theme() { do ...

Converting the following ngRx selector to a boolean return – a guide

I am currently using the following filter to retrieve a list of data within a specific date range. I have implemented logic in the component where I check the length of the list and assign True or False to a variable based on that. I am wondering if ther ...

Retrieve element attributes and context inside a function invoked by an Angular directive

When working with a directive definition, you have access to the $element and $attrs APIs. These allow you to refer back to the element that called the directive. However, I'm curious how to access $element and $attrs when using a standard directive l ...

Dependency on Angular's HTTP service inside a component

I've been experimenting with loading data from a static JSON file as part of my journey to learn angular templating. After some searching online, I came across a few examples. However, I want to steer clear of implementing a service until I have a be ...

Is it possible to submit a form through a JavaScript hotkey?

Here's the current code that I'm working with: <select tabindex="2" id="resolvedformsel" name="resolved"> <option selected="selected" value="yes">resolved</option> <option value="no">not resolved</option> ...