Converting JavaScript code for Angular: A step-by-step guide

I have been working on integrating a feature similar to the one demonstrated in this Angular project: https://codepen.io/vincentorback/pen/NGXjda

While the code compiles without any issues in VS code, I encountered two errors when attempting to preview it in the browser:

  1. Uncaught (in promise): TypeError undefined is not an object (evaluating 'this.context.addEventListener')
  2. TypeError undefined is not an object (evaluating 'this.getScrollPos')

Stackblitz: https://stackblitz.com/edit/ionic-rv4ju7

home.page.ts

export class HomePage implements OnInit {

  context = document.getElementsByClassName('loop')[0];
  startElement = document.getElementsByClassName('is-start')[0];
  clones = document.getElementsByClassName('is-clone');
  disableScroll = false;
  scrollWidth;
  scrollPos;
  clonesWidth;
  i;

  constructor() { 
    window.requestAnimationFrame(this.reCalc);
    this.context.addEventListener('scroll', function () {
      window.requestAnimationFrame(this.scrollUpdate);
    }, false);
    window.addEventListener('resize', function () {
      window.requestAnimationFrame(this.reCalc);
    }, false);
  }

getScrollPos() {
    return (this.context.pageXOffset || this.context.scrollLeft)  - (this.context.clientLeft || 0);
  }
  setScrollPos(pos) {
    this.context.scrollLeft = pos;
  }
  getClonesWidth() {
    this.clonesWidth = 0;
    this.i = 0;

    for (this.i; this.i < this.clones.length; this.i += 1) {
      this.clonesWidth = this.clonesWidth + this.clones[this.i].clientWidth;
    }
    return this.clonesWidth;
  }
  reCalc() {
    this.scrollPos = this.getScrollPos();
    this.scrollWidth = this.context.scrollWidth;
    this.clonesWidth = this.getClonesWidth();

    if (this.scrollPos <= 0) {
      this.setScrollPos(1);
    }
  }
  scrollUpdate() {
    if (this.disableScroll === false) {
      this.scrollPos = this.getScrollPos();

      if (this.clonesWidth + this.scrollPos >= this.scrollWidth) {
        // Scroll to the left when you’ve reached the far right
        this.setScrollPos(1); // Scroll 1 pixel to allow scrolling backwards.
        this.disableScroll = true;
      } else if (this.scrollPos <= 0) {
        // Scroll to the right when you reach the far left.
        this.setScrollPos(this.scrollWidth - this.clonesWidth);
        this.disableScroll = true;
      }

      if (this.disableScroll) {
        // Disable scroll-jumping for a short time to avoid flickering.
        window.setTimeout(function () {
          this.disableScroll = false;
        }, 40);
      }
    }
  }

}

Answer №1

Consider moving your code from the constructor to AfterViewInit in order to access DOM elements more effectively. It's recommended to keep logic out of the constructor, which is primarily for initializing variables.

Another issue to address is understanding the use of this. For better clarity on this topic, check out: How to access the correct `this` inside a callback? This will help you grasp the concept and why using arrow functions might be more suitable than regular functions to maintain the context of this.

For example, convert:

this.context.addEventListener('scroll', function () {

to:

this.context.addEventListener('scroll', () => {

Feel free to explore this modified version of your StackBlitz

PS: Utilize Angular tools whenever possible instead of directly manipulating the DOM with methods like .getElementById. Angular provides its own tools that should be prioritized over direct DOM manipulation within components.

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

Navigating the world of getElementById and addEventListener outside of the DOM

Having some dynamic HTML code in my JS, I'm hoping to assign an ID to a particular tag: content: ` <p id="openKeyboard"> If the click happens, I want to trigger an event. </p> ` However, upon ...

I am having trouble getting the hoverOffset feature to work with doughnut charts in vue-charts.js

It appears that no matter what I try, the hoverOffset property is not working on my doughnut charts. Here's the component code: <script> import { Doughnut } from 'vue-chartjs' export default { extends: Doughnut, props: { ch ...

What are some ways to access my AsyncStorage data from any location?

I am utilizing the saga library and storing tokens in AsyncStorage. My goal is to be able to freely access the token retrieved from AsyncStorage in both the loadUserPosts function and the loadPosts function. Where should I add async and how can I correct ...

Preventing page navigation in JavaScript: Why it's so challenging

I am encountering an issue with a link element that I have bound a click event to (specifically, all links of a certain class). Below is an example of the link element in question: <a id="2" class="paginationclick" style="cursor: pointer;" href=""> ...

Combining element.scrollIntoView and scroll listener for smooth scrolling by using JavaScript

Can element.scrollIntoView and a "scroll" event listener be used simultaneously? I'm trying to create code that checks if the user has scrolled past a certain element, and if so, automatically scrolls smoothly to the next section. I attempted to achi ...

Instructions on creating a number increment animation resembling Twitter's post engagement counter

I've been attempting to replicate the animation seen on Twitter's post like counter (the flipping numbers effect that happens when you like a post). Despite my best efforts, I can't seem to make it work. Here is what I have tried: $(fun ...

Updating the value of a localStorage key after each successful AJAX call in JavaScript

I'm currently facing a challenge with my local storage key value. The issue is that it doesn't update the value when the AJAX call successfully returns data. It only retains the old stored data, requiring me to manually refresh the page by pressi ...

Tips for establishing and connecting numerous connections among current nodes using the same criteria

While browsing StackOverflow, I came across similar questions. However, I believe this one has a unique twist. The main issue at hand is: How can I establish multiple relationships between existing nodes? I have the following code snippet: session . ...

Iterating through every image displayed on a webpage

Two inquiries: What is the best way to efficiently loop through every image on a specific webpage and open each one in a new browser tab? Similar concept, but instead of opening in a new tab, I am interested in substituting different images for the ...

How can you utilize a previously opened window from another page in JavaScript?

One of my challenges involves managing windows in a JavaScript environment. When I open a child window using window.open("http://foobar","name"), it reuses the same window when opened with the same name, which is exactly what I want. However, if the origi ...

What is the best way to retrieve the href and id values dynamically from a card in React JS?

Hello everyone, I'm new to stackoverflow and still in the process of learning how to code. Please bear with me if this question sounds like a newbie one. My question is about having dynamic values for href and id when mapping data using axios to crea ...

Unable to include Authenticated Routes in react router dom

Currently, I am utilizing react-router-dom to manage routing for users who are authenticated and non-authenticated. However, I have encountered an error in Element due to missing properties. Is there a way to make withoutAuth() function properly for authe ...

Changing properties of a parent component from a child component in Angular 2

Currently, I am utilizing the @input feature to obtain a property from the parent component. This property is used to activate a CSS class within one of the child components. Although I am successful in receiving the property and activating the class init ...

Explore the possibilities of using a unique custom theme with next.js, less, and ant design

Trying to customize the default theme in antdesign has been a challenge for me. I've switched from sass to less, but there seems to be something that just won't work. I've exhaustively searched online for solutions - from official nextjs ex ...

Is it possible to iterate over a non-reactive array in a Vue template without having to store it in a data property or computed property?

Presented below is a static array data: const colors = ["Red", "Blue", "Green"]; To display these values in my markup, I can use the following method in React: import React from "react"; // Static array of colors const colors = ["Red", "Blue", "Green"] ...

Remove the list by conducting a comparison analysis

<html> <head> <title> Manipulating List Items Using JavaScript </title> <script type="text/javascript"> function appendNewNode(){ if(!document.getElementById) return; var newlisttext = document.changeform.newlist.val ...

Is there a problem with the Drag and Drop API?

So here's the deal: I've encountered a problem with the HTML5 Drag and Drop API. In short, besides the essential dragstart, dragover, and drop events, there are three more events - mousedown, mouseup, and mouseleave - that are crucial for achiev ...

The hidden DIV containing an ASP.NET CheckBox consistently yields a value of false

I have a group of form elements located within a hidden div which looks like this: <div id="jDivUpdateFolder" style="display:none;"> <asp:TextBox ID="txtEditFolderName" runat="server"></asp:TextBox><br /> <asp:TextBox ID ...

Is there a way to access the HTML and CSS source code without using the inspect feature

I'm working on a project that involves an "edit box" where users can write text, add emojis, change the background color, insert images, and more. After users finish creating their content, I want them to be able to send it via email. This means I ne ...

Remove the ID, class, and other attributes from an HTML string using JavaScript for sanitization purposes

Can someone help me with sanitizing HTML text provided by a user? The HTML code in question is as follows: var htmlStr = `<p id="test" class="mydemo">TEhis is test</p> <pre class="css"> &lt;html> &lt;body cl ...