Unusual Interpolation Issues in Angular 10

I've encountered an unusual issue while working with Angular 10.

The problem arises when I remove a specific element, everything functions correctly. The desired behavior is that when the div.passRide is clicked on, it should update another component using the updateViewer(passRide.id) method to fetch and display a particular record.

However, when I try to retrieve certain fields from getCrewDiagram(id) in selector.ts, it seems like every div has been clicked on, causing the viewer to update and display the last item in the list of divs consistently.

I have come across similar questions here, but they don't address my specific issue. I suspect it might be something fundamental that I'm overlooking.

selector.htm:

<div id="passes">
  <div class="passRide" *ngFor="let passRide of context.getPassRides();" (click)="updateViewer(passRide.id)">
    
  <p>{{ getCrewDiagram(passRide.id).header.diagNumber }}</p> <<<---- problematic element here

    <table>
      <tr *ngFor="let event of passRide.events">
        <td>{{ event.activity.diagramActivity }}</td>
        <td>{{ event.noteLine ? event.note : (event.reliefLine ? event.reliefs : event.location.shortDesc) }}</td>
        <td>{{ event.activity.diagramActivity == "DEP" || event.activity.diagramActivity == "ARR" ? event.eventTime : ""}}</td>
        <td>{{ event.activity.diagramActivity == "DEP" ? event.wttid : ""}}</td>
      </tr>
    </table>
  </div>
</div>

selector.ts

import { Component, OnInit } from '@angular/core';
import { CrewDiagram } from '../../core/crew-diagram';
import { DiagramSetService } from '../../core/current-diagram-set.service';

@Component({
  selector: 'app-selector',
  templateUrl: './selector.component.html',
  styleUrls: ['./selector.component.css']
})
export class SelectorComponent implements OnInit {

  constructor(public context: DiagramSetService) { }

  ngOnInit() {
  }

  updateViewer(index: number) : void {
    this.context.setCrewDiagram(index);
  }

  updateViewerDebug(index: number, $event): void {
    console.log($event)
    this.context.setCrewDiagram(index);
  }

  getCrewDiagram(id: number): CrewDiagram {
    return this.context.getCrewDiagram(id);
  }
}

diagram-set-service.ts

import { Injectable } from '@angular/core';
import { CrewDiagram } from './crew-diagram';
import { CrewPuzzlePiece } from './crewPuzzlePiece/crew-puzzle-piece';

@Injectable({
  providedIn: 'root'
})
export class DiagramSetService {

  constructor() { }

  crewDiagrams: CrewDiagram[] // Original set from which the following are derived
  crewDiagram: CrewDiagram    // Current crew diagram (used by viewer/diagramViewer)
  filteredView: CrewDiagram[] // Diagrams on show at the moment

  passRides: CrewPuzzlePiece[] // Diagram puzzle pieces representing passing moves

  getCrewDiagrams(): CrewDiagram[] {
    return this.crewDiagrams;
  }

  getFilteredDiagrams(): CrewDiagram[] {
    return this.filteredView;
  }

  setCrewDiagrams(crewDiagrams: CrewDiagram[]) {
    this.crewDiagrams = crewDiagrams;
    this.filteredView = crewDiagrams;
  }

  getCrewDiagram(id: number): CrewDiagram{
    console.log("getCrewDiagram" + id);

    return this.crewDiagram = this.crewDiagrams.
      filter(
        function (diagram, index, array) {
          return diagram.id == id;
        }
    )[0];
  }

  setCrewDiagram(id: number): void {
    this.crewDiagram = this.getCrewDiagram(id);
    console.log("setCrewDiagram" + id);
  }

  getNumberCrewDiagrams() {
    if (!this.crewDiagrams) {
      return 0;
    }

    return this.crewDiagrams.length;
  }

  getCurrentCrewDiagram() {
    return this.crewDiagram;
  }

  filterCrewsByDepot(depotString: string): void {
    const depots = depotString.split(' ');

    this.filteredView = this.crewDiagrams.filter(function (diagram) {
      return depots.includes(diagram.header.depot);
    });
  }

  resetView(): void {
    this.filteredView = this.crewDiagrams;
  }

  setPassRides(passRides: CrewPuzzlePiece[]): void {
    this.passRides = passRides;
  }

  getPassRides(): CrewPuzzlePiece[] {
    return this.passRides;
  }
}

Debug output when the problematic element is removed: https://i.sstatic.net/MyaCk.png

Debug output when the problematic element is present: https://i.sstatic.net/kWX9q.png

Answer №1

The issue arises from binding to a method call in your code.

*ngFor="let passRide of context.getPassRides();"

and

<p>{{ getCrewDiagram(passRide.id).header.diagNumber }}</p>

Upon interaction, Angular's ChangeDetection triggers, causing the entire content to be reconstructed. By binding your ngFor and paragraph with a method, the list is reconstructed repeatedly, leading to continuous calls to getPassRides() and getCrewDiagram().

To address this, it is recommended to prepare/map your model, this.crewDiagrams, and then perform property binding similar to how it's done for <tr>

<div id="passes">
    <div class="passRide" *ngFor="let passRide of context.getPassRides" (click)="updateViewer(passRide.id)">

        <p>{{ passRide.header.diagNumber }}</p>

        <table>
            <tr *ngFor="let event of passRide.events">
                ...

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

Is the CanActivate Observable for boolean values malfunctioning or should I use EventEmitter.asObservable() instead in Angular2?

Check out my code using Observable and EventEmitter here: http://plnkr.co/edit/HV2sWd?p=preview Even with publishReplay, I'm still facing issues :( I have a feeling it has something to do with EventEmitter.asObservable() Can you help me figure out ...

Clearing error messages from a form using the reset button or after cancelling the form

I am having trouble removing the error outline around the input box and error messages displayed below it. When I cancel the form or click on the reset button, the input fields' content along with the error messages should be cleared. However, current ...

Leveraging CSS attribute selectors within JSX using TypeScript

With pure HTML/CSS, I can achieve the following: <div color="red"> red </div> <div color="yellow"> yellow </div> div[color="red"] { color: red; } div[color="yellow"] { color: yellow; ...

Patience is key as we anticipate the parent component/module loading the data

Just a note: I am aware of the existence of APP_INITIALIZER, but it appears to only work in the top-level module (app.module.ts) of the application. I have a parent component that loads some data: In admin-area.component.ts: ngOnInit(): void { forkJo ...

Utilizing a personalized directive within a ionic popup

I am currently using the ion-textarea autosize directive: import { Directive, HostListener, ElementRef } from '@angular/core'; @Directive({ selector: 'ion-textarea[autosize]' }) export class AutoResizeTextareaDirective { readonly ...

Is it possible to begin utilizing Angular 2 without requiring Node?

I am interested in experimenting with using angular 2 for VS 2015, however, the first requirement is having node.js. To my understanding, do I need node.js as a web server and npm to download packages? Is it possible to achieve the same goal using IIS an ...

Why is there a discrepancy between the value displayed in a console.log on keydown and the value assigned to an object?

As I type into a text box and log the keydown event in Chrome, I notice that it has various properties (specifically, I'm interested in accessing KeyboardEvent.code). Console Log Output { altKey: false bubbles: true cancelBubble: false cancelable: t ...

Using Vue with TypeScript: A Necessary Prop

I recently utilized the vue-property-decorator to add a required prop to my component class. However, when I attempted to use the component without passing the prop, no console errors were displayed indicating that the required prop is missing. Why did thi ...

Is there a way to export a specific portion of a destructuring assignment?

const { a, ...rest } = { a: 1, b: 2, c: 3 }; If I want to export only the rest object in TypeScript, how can I achieve that? ...

The property X within the ClassB type cannot be assigned to the identical property within the parent type ClassA

I deal with the following set of Typescript classes: Firstly, we have an abstract class export abstract class MyAbstractClass { ... } Next is Class A which implements the methods from the abstract class export ClassA extends MyAbstractClass { ...

I'm looking to locate the API documentation for AngularJS TypeScript

After transitioning from using AngularJS 1.4 and plain JavaScript to now working with AngularJS 1.5 but utilizing TypeScript, I have found it challenging to find helpful documentation. For instance, when trying to inject services like $q or $timeout into m ...

How can I resolve the problem of transferring retrieved data to a POST form?

When it comes to the form, its purpose is to send data fetched from another API along with an additional note. The fetched data was successfully received, as I confirmed by logging it to the console. It seems that the form is able to send both the fetche ...

Guide to creating a one-to-one object literal map with a different value type using a function return without explicitly defining the return type

At the moment, I have successfully managed to combine the keys and values of each object literal that is passed into a function. For example: interface StaticClass<T = any> { new (...args: any[]): T } type RecordOfStaticClasses = Record<string, ...

Testing Angular - using observables that return varying values

I'm currently faced with the challenge of testing a component that subscribes to an observable in a service during its ngOnInit lifecycle hook. The component's behavior is expected to change based on the value received from the observable. To sim ...

Encountering issue where the Angular application within the UWP project fails to load the second

I am facing a challenge with integrating my Angular project into a Universal Windows Platform (UWP) application. The Angular code functions flawlessly in the browser, but once incorporated into the UWP bundle, I encounter navigation issues. Technical Stac ...

I'm having trouble with one of my filter pipes not displaying any results. Can anyone help me troub

I have recently included a new filter for DL, but it seems that the results are not showing up as expected. Any ideas on what changes I should implement? <div class="form-group float-left mr-4"> <strong>DL</strong> <br /> ...

Issues with running Angular 2-4 SETUP on Windows operating system

I recently started working with Angular 2/4 and everything was running smoothly until I followed the instructions on https://github.com/angular/angular-cli. I have Angular 2-4 installed on my machine, but after a recent Windows update, I encountered issues ...

Solving the error message "Cannot find module '@angular/router/src/utils/collection' or its corresponding type declaration"

How do I troubleshoot this Error: src/app/metronic/orderByLocation/locationsByOneOrder/locationsByOneOrder.component.ts:7:25 - error TS2307: Cannot find module '@angular/router/src/utils/collection' or its corresponding type declarations.m 7 imp ...

Utilize the imported function from <Script> within NextJS

When working with vanilla JS, I am able to include a script like this: <head> <script src="https://api.site.com/js/v1/script.js"></script> </head> and then create an instance of it using: const fn = ScriptJS(); I can t ...

Encountering an Issue with Generating PDF from HTML in Angular 8 with jsPDF

I am currently working with angular 8 Although I am trying to generate a PDF, I am encountering an issue This is my HTML code snippet <div id="content" #content> <h1>The Title</h1> <p>{{name}}</p& ...