What is the best approach for implementing recursion within a foreach loop in TypeScript?

Problem Situation

I am attempting to develop a customized typewriting effect similar to the one demonstrated here with a 100ms delay using Angular.

The TypeScript code I have written for this purpose is as follows:

private arr: string[] = ["Lead Developer (.NET)", "Full Stack (.NET) Developer", "Freelancer"];
private typewriter_text: string = "";
private typewriter_display: string = ""; 

ngOnInit() {
    this.typingInitiating(this);
}

typingInitiating(that) {
    this.arr.forEach(element => {
      that.typewriter_text = element;
      this.typingCallback(that);
    });
}

typingCallback(that) {
    if (this.typewriter_display.length < that.typewriter_text.length) {
      this.typewriter_display += that.typewriter_text[this.typewriter_display.length];  
      setTimeout(that.typingCallback, 100, that);
    }
    else {
      for (let i = that.typewriter_text.length; i >= 0; --i) {
        this.typewriter_display = that.replaceAt(that.typewriter_text, i,that.typewriter_text.length - i);
        console.log(this.typewriter_display)
      }
    }
}

replaceAt(text: string, index: number, charcount: number): string {
    return text.substr(0, index) + text.substr(index + charcount);
}

In my App.Component.html:

{{typewriter_display }}

Live Stackblitz

An error message appears in the console:

https://i.sstatic.net/aEhB9.png

https://stackblitz.com/edit/angular-rqtvoz

I am curious about why my recursive function is not functioning as intended.

Answer №1

In this scenario, the reference to this is being lost within the function, as it does not point back to the object itself. Each function that is created possesses its own context for this. To resolve this issue, we should transition to utilizing an Arrow function, which avoids binding its own this.

typingCallback = (that: any) => {

 if (this.typewriter_display.length < that.typewriter_text.length) {
  this.typewriter_display += 
  that.typewriter_text[this.typewriter_display.length];  
  setTimeout(that.typingCallback, 100, that);
}
else {
  for (let i = that.typewriter_text.length; i >= 0; --i) {
    this.typewriter_display = that.replaceAt(that.typewriter_text, 
   i,that.typewriter_text.length - i);
     console.log(this.typewriter_display)
   }
 }

};

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

Typescript type/object's conditional property feature

Imagine having a recipe ingredient type structured like this export type RecipeIngredient = { name: string; amount: Number | string; unit: "grams" | "milliliters" | "custom"; }; To illustrate const apples: RecipeIngredient = { name: 'apples&a ...

Here is the unique rewrite: "Learning how to write true or false tests in Jasmine for Angular can be tricky, especially when encountering the error message: 'Argument of type is not assignable to

I have a function that is supposed to return true or false, as shown below. However, I am encountering an error saying Argument of type 'true' is not assignable to parameter of type 'Expected<void>'. Can you help me identify where ...

Enhance Tuple in Angular Component Properties

When using React, state variables can be created like this: const SomeComponent = ({ someProp }) => { const [value, setValue] = useState<boolean>(false); } I wonder if there is a similar way to achieve the spread of a tuple within an Angular co ...

I am interested in creating an input range slider using React and TypeScript

This code was used to create a slider functionality import { mainModule } from 'process'; import React, { useState } from 'react'; import styled from 'styled-components'; const DragScaleBar = () => { const [value, setV ...

"Transforming a Java byte array into a ReactJS video: Step-by-step guide

I am getting a file from a Java API server and need to convert it into a video using React JS. The Java API server converts the video file into a byte array using Files.readAllBytes(file) and I need to use this video file byte array to create a video fil ...

An easy guide to adding animation to an image with just a click using angular-animations

I have a cool animation that currently triggers when the page loads. However, I want to change it so that the image animates on a button click instead. <div [@fadeInDownOnEnter]="'true'"> <img src="https://www.seoclerk.com/pics/5567 ...

The error message "Angular 4 does not recognize the 'dragula' property as a valid property of the 'div' element" is displayed

Struggling to integrate ng2-dragula with the AspNetCore SPA template. Despite trying various solutions, I am still encountering the following error: Exception: Call to Node module failed with error: Error: Template parse errors: Can't bind to 'd ...

Custom Mui table sizes - personalized theme

By implementing custom sizes for the Table component in Material UI, I have extended the Table size prop with the following declaration: declare module '@mui/material' { interface TablePropsSizeOverrides { relaxed: true large: true } ...

Repetitive process in JavaScript

I am struggling to write certain attributes to HTML using a recursive loop and I can't seem to get the code to work properly. The JSON data consists of an array of hashes with the following attributes: serno (serial number), parent_serno (serial numb ...

The CORS policy specified in next.config.js does not appear to be taking effect for the API request

I am currently working on a Next.js application with the following structure: . ├── next.config.js └── src / └── app/ ├── page.tsx └── getYoutubeTranscript/ └── getYoutubeTranscript.tsx T ...

The json.parse function can be used in JavaScript, but it is not compatible with Angular

Currently, I am in the process of converting an existing JavaScript application into Angular using TypeScript. In the original JavaScript application, I have a JSON data file that is successfully read during startup. However, when attempting to read the ex ...

The input feature in the Angular 4 Library allows users to easily

Hello everyone, I could really use some assistance with a problem I am facing. For some reason, I can't seem to make it work properly. I suspect that there might be an issue with the syntax I am using. Currently, I am in the process of developing Ang ...

How to build a login page with a static header and footer using Angular2

For my latest project, I am currently in the process of developing an application using Angular2 and eclipse Neon. Utilizing angular-cli for this app, I am now focused on creating the login page. Within the app.component.html file, you will find the follow ...

The logs of both the frontend and backend display an array of numbers, but surprisingly, this data is not stored in the database

I am attempting to recreate the Backup Codes feature of Google by generating four random 8-digit numbers. for(let i = 0; i < 4; i++) { let backendCode = Math.floor(Math.random() * (99999999 - 10000000 + 1) + 10000000); backendCodes.push(back ...

Obtain a personalized response from an Angular HTTP service

I'm trying to implement the following code directly in a component: if(exampleService.checkValidityOfToken()) { //do something } Here is the method in exampleService that corresponds to this. I'm not sure if I am returning the value properly or ...

What is the procedure for transferring the inputted data from an HTML file to its corresponding TS file and subsequently to a different component file?

I have created two components, a login and a home-page. I am attempting to capture user input from the login template, pass it to the login component, and then display it on the home-page template using the home-page component. What is the best approach to ...

NestJS's "Exclude" decorator in class-transformer does not exclude the property as expected

I attempted to exclude a specific property within an entity in NestJS, but it appears that the exclusion is not working as expected. When I make a request, the property is still being included. Code: // src/tasks/task.entity.ts import { Exclude } from &ap ...

Is it possible to assign a string literal type as a key in TypeScript mappings?

Is it possible to map a string literal type as a key in a new type? I attempted this, but it did not work as expected. const obj = { type: "key", actions: { a() {}, b() {}, }, } as const; /* Map to { key: { a() {}, b() {}, } */ t ...

Use vertical gaps to separate items by applying the following technique:

One of my components is designed to act as a badge. The CSS for this component includes: https://i.sstatic.net/F0QZ6.png HTML: <div class="label label-as-badge"> {{ value.Termo }} <i class="fa fa-times"></i ...

Identify the category of the component

Using a Link component from version 4.0.0-beta.2, I am exploring its capability to override the root element with a field called component. My goal is to wrap the Link component in a new component called MyLink and pass a custom component through props: ...