Undefined output in Typescript recursion function

When working with the recursion function in TypeScript/JavaScript, I have encountered a tricky situation involving the 'this' context. Even though I attempted to use arrow functions to avoid context changes, I found that it still did not work as expected.

The code snippet is provided below:

export interface Item {
    label: string;
    items?: Item[];
}

export class BannerTreeModel {
    rootItems: Item[] = [];

    getMaxDepthSubtree(root_item: Item) {
        let max_depth = 0;
        if (root_item.items) {
            root_item.items.forEach((child) => {
               max_depth = Math.max(max_depth, this.getMaxDepthSubtree(child));
            });
        }
        return ++max_depth;
    }
}

To call this function, you can use the following code:

let model: BannerTreeModel = new BannerTreeModel();
model.rootItems = [{ label: 'item1', items: [{label: 'item2'}, {label: 'item3'}] }];
model.getMaxDepthSubtree(model.rootItems[0]);

During debugging, I noticed that this within the line this.getMaxDepthSubtree(child)) was undefined, resulting in an error stating

undefined function getMaxDepthSubtree
. Can anyone offer suggestions on how to resolve this issue?

Answer №1

When using forEach, the context of this refers to the global window object.

To work around this issue, you can store the class context in a variable called _this:

export class BannerTreeModel {
    rootItems: Item[] = [];
    var _this = this;

    getMaxDepthSubtree(root_item: Item) {
        let max_depth = 0;
        if (root_item.items) {
            root_item.items.forEach((child) => {
               max_depth = Math.max(max_depth, _this.getMaxDepthSubtree(child));
            });
        }
        return ++max_depth;
    }
}

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

Having trouble maintaining the initial state of the first accordion in a foreach loop

I have a collapsible accordion here, which is functioning well with static data. Now, I have connected it to a database and am attempting to retrieve data from the database. Below is the code I have implemented so far in CodeIgniter, View: <div class= ...

Do you need to finish the Subject when implementing the takeUntil approach to unsubscribing from Observables?

In order to prevent memory leaks in my Angular application, I make sure to unsubscribe from Observables using the following established pattern: unsubscribe = new Subject(); ngOnInit() { this.myService.getStuff() .pipe(takeUntil(this.unsubscr ...

Vue: Utilizing computed properties to monitor changes in offsetHeight of elements

I am working on a component that requires an array of 50 objects to be passed as a prop. <template> <div v-for="(item,index) in items" ref="items" :key="index"gt; // </div> </template> props: ...

Exploring the Canvas with Full Element Panning, Minimap Included

Currently, I am working on incorporating a mini map onto my canvas that mirrors what is displayed on the main canvas. The main canvas includes zoom and pan functions. I have created a rectangular shape for the minimap to display the content of the canvas. ...

The issue with calling a public method from an onchange event triggered by a custom Google Maps control in the Ionic framework has been encountered

Hello, fellow developers! I am relatively new to Ionic and web programming in general. Currently, I am working on a small app that involves integrating the Google Maps JS API. While I have successfully created and loaded the map, as well as added a custom ...

Angular does not completely erase everything

Having some issues with file deletion while working on angular and typescript. My setup involves three interfaces: Project, SubProject, and Position. When a subproject is added to the selected project, it gets included in the subProjectIds list of the Proj ...

Looking to utilize Axios in React to make API calls based on different categories upon clicking - how can I achieve this?

My current issue involves making an API call upon clicking, but all I see in my console is null. My goal is to have different API categories called depending on which item is clicked. const [category, setCategory] = useState(""); useEffect(() => { ...

Determine the Total of Various Input Numbers Using JQuery

There are 3 input fields where users can enter numbers, and I want to calculate the sum of these numbers every time a user updates one of them. HTML <input class="my-input" type="number" name="" value="0" min="0"> <input class="my-input" type="n ...

Is it possible to implement a different termination condition when using *ngFor in Angular 2?

After countless hours of searching on Google, I have yet to discover a method for implementing an alternative stop condition for loops created with the *ngFor directive. By default, *ngFor loops end with this condition: index < array.length. Is there a ...

Utilizing JavaScript and Ajax to Dynamically Assign Variables Based on JSON Responses

What could be causing the undefined value of x at line 11, even though it was defined in line 9? <script> var x; $.ajax({ dataType: "json", url: myurl, success: function(data){ console.log(data); x = data; documen ...

Navigating through the properties of a JSON object and traversing the React state leads to encountering the error message 'state undefined'

Apologies if I seem a bit lost, but I'm attempting to assign a JSON object to a component's state for rendering purposes. This is the current setup within my component: render: function() { this.serverRequest = $.get(this.props.source, func ...

What is the best way to include a substantial amount of HTML in a Vue.js template?

As a newcomer to Vue.js, I have a question regarding the rendering of a large amount of HTML in a Vue.js template. When I include around 500 lines of plain HTML code in my template and run npm run dev the compiling process becomes extremely slow or d ...

Issue with setting .mtl properties in a custom shader in three.js

In my custom three.js application, I am loading an OBJ/MTL model for rendering. I am trying to apply a custom shader to the model, but the color and specular uniforms that I manually pass to the RawShaderMaterial are not updating correctly. Instead, they a ...

Viewing an image from a local file on a web browser

I am currently working on a project where I want the user to be able to select a local image that will then be displayed on the page. As someone who is new to web development, I did a lot of research and found some helpful information on StackOverflow. I t ...

Reverting to the original order in jQuery DataTables after dropping a row

Recently, I've been attempting to utilize jQuery DataTables in conjunction with the Row Ordering plugin. At first, everything seemed to be functioning properly until a javascript error popped up indicating an unrecognized expression. After researching ...

The Vue instance seems to be unable to recognize the shims-vue.d.ts file

I encountered an issue with my Vue file. Here is the code snippet: import Vue from 'vue'; import VueRouter from 'vue-router'; export default Vue.extend({ name: 'MyComponentsName', methods: { doRedirect() { this. ...

Deleting database information using Jquery when a div is clicked

I'm looking to create an alert system where users will see a pop-up alert on their screen. However, I am facing a major issue in removing the div completely. I understand that I need to remove it from the database, but I'm struggling with finding ...

ERROR: Unhandled promise rejection: Unable to find a matching route for URL Segment 'main/knowledge-base'

After setting up dynamic routing for my Angular 6 application, I encountered an error when clicking on a link (for example, 'knowledge base') that stated: core.js:1673 ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segme ...

Converting a Luxon DateTime object into a standard date

Currently, I am constructing a DatePicker React component utilizing the Material-UI picker library and integrating Luxon as an adapter. Whenever I modify the calendar date, I receive an object containing DateTime information as shown below: This is the co ...

Unlock the full potential of integrating external APIs with Next.js

As a newcomer to NextJs, I am facing the task of making calls to an external Python API from my frontend. Upon discovering NextJs's integrated API feature through creating folders in the app directory, namely api/resource/route, I am wondering what th ...