Problem occurs when ngFor directive fails to show the newly added data in the source array

I'm encountering a peculiar issue with an ngFor loop that handles new data being added to the source array. The newly added elements are briefly displayed in the DOM but then disappear almost instantly. I've found a workaround by manually calling the ChangeDetector's detectChanges method, although it's worth noting that the element remains visible for a longer period when running in production mode. I've carefully checked all components to ensure they're not being reloaded and scrutinized API calls to confirm that the data isn't being refetched, leading me to believe that the root cause lies in the removal of data from the source array immediately after addition.

The fresh data is delivered to the application through a SignalR event, which makes me question if there might be some connection there. While I suspect the issue originates from my own logic, I'm struggling to identify any factors that could possibly trigger this behavior.

The boardEntries array in the BoardColumnComponent is where the data gets appended.

BoardColumnComponent.ts

export class BoardColumnComponent implements OnInit {
@Input() columnIndex: number;
@Input() columnData: BoardColumnModel;
@Input() boardEntries: Array<BoardEntryModel>;

backgroundColour: string;

constructor(private signalEventsService: SignalEventsService,
            private changeDetector: ChangeDetectorRef,
            private applicationRef: ApplicationRef) { }

ngOnInit() {
    console.log ("Column Init")
    this.backgroundColour = BoardColours[this.columnIndex];

    this.signalEventsService.boardDataEventEmitter.subscribe(res => {
        var boardEntryModel = new BoardEntryModel();
        Object.assign(boardEntryModel, res);

        if (boardEntryModel.ColumnIndex == this.columnIndex) {
            this.boardEntries.push(boardEntryModel);
            this.changeDetector.detectChanges();
        }
    });
}

Below is the HTML code:

board-column.component.html


<div class="board-column" [style.background-color]="backgroundColour">
    <div class="board-column-header">
        <h3>{{ columnData.ColumnName }}</h3>
    </div>
    <app-board-entry *ngFor="let boardEntry of boardEntries" [boardEntry]="boardEntry"></app-board-entry>
</div>

Next, we have the board-entry.component.ts file:

export class BoardEntryComponent implements OnInit {
    @Input() boardEntry: BoardEntryModel;

    constructor() { }

    ngOnInit() {
        console.log ("Entry Init")
    }
}

And its corresponding HTML template:

<div class="board-entry-container">
    <p>{{ boardEntry.EntryContent }}</p>
</div>

If more code is needed for further assistance, please let me know. Any help would be greatly appreciated.

Answer №1

To start off, if you consistently receive the res of type BoardEntryModel, it's advisable to specify the expected data type for your res by adding res:BoardEntryModel. This way, there is no need to instantiate a new object each time.

Additionally, depending on how your logic is set up, the subscription might be triggered again upon data injection.

Therefore, prior to appending data to the array, include the condition if(res) to bypass further steps when nothing is captured.

Would you consider updating your .ts file with the provided code snippet?

   export class BoardColumnComponent implements OnInit {
@Input() columnIndex: number;
@Input() columnData: BoardColumnModel;
@Input() boardEntries: Array<BoardEntryModel>;

backgroundColour: string;

constructor(private signalEventsService: SignalEventsService,
            private changeDetector: ChangeDetectorRef,
            private applicationRef: ApplicationRef) { }

ngOnInit() {
    console.log ("Column Init")
    this.backgroundColour = BoardColours[this.columnIndex];

    this.signalEventsService.boardDataEventEmitter.subscribe((res:BoardEntryModel)=> {
          if(res){
        // var boardEntryModel = new BoardEntryModel();
        // Object.assign(boardEntryModel, res); 

        if (res.ColumnIndex == this.columnIndex) {
            this.boardEntries.push(res);
            this.changeDetector.detectChanges();
        }}
    });
}

Answer №2

After some investigation, I couldn't find the cause of the component reloading issue. As a temporary solution, I have relocated the SignalR subscription logic to the parent component and it seems to be functioning properly at the moment. Thank you for your assistance.

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 is the best way to implement generics for a zip function in TypeScript?

I want to enhance this JS function by including types: function zip(array1, array2) { const length = Math.min(array1.length, array2.length); const result = []; for (let i = 0; i < length; i++) { result.push([array1[i], array2[i]]); } retur ...

Add an asterisk before each line of comment when working in a TypeScript file using the VS Code IDE

Within my VS Code workspace, I am using the Typescript language and would like to format my comments across multiple lines with a specific style (look out for the star character) /** *@desc any text * any text */ However, when I attempt to write a comm ...

Searching for an Angular component in Selenium

After reviewing the HTML code snippet below, <div class="dx-filterbuilder-action-icon dx-icon-plus dx-filterbuilder-action" tabindex="0"> ::before </div> I attempted to locate this element using Selenium C# with the followin ...

Utilizing the Kraken.com API to create a message signature with AngularJS

I'm currently tackling Angular2 and for my first project, I want to tap into the Kraken.com API. (I know, I could have chosen an easier task :) The "Public" calls are working smoothly, but I've hit a snag with the "Private" methods. (Those requi ...

Angular 8 and the conundrum of date parsing issues

const timestamp = '2020-07-11T00:05:00'; const dateOfFlight = new Date(timestamp); dateOfFlight.getMonth() // The output should be 6 However, it is expected to be 7 based on the provided timestamp. ...

Encountering a problem with the mock object in Angular 11 unit testing when converting a JSON object to a TypeScript interface

Within my Angular 11 application, I am working with a JSON response and have defined an interface to match the structure of this JSON object. The JSON object looks like this: { "division": { "uid": "f5a10d90-60d6-4937-b917- ...

What is the method to access an interface or type alias that has not been explicitly exported in TypeScript type definitions?

I am looking to create a new class that inherits from Vinyl. The constructor in the superclass takes a single parameter of type ConstructorOptions. export default class MarkupVinylFile extends Vinyl { public constructor(options: ConstructorOptions) { ...

iOS 13 causing input field to be covered by keyboard on Ionic v4

I've been grappling with this persistent bug for quite some time now, but unfortunately, I haven't been able to make any headway in resolving it. The issue arises when I click on an input field, causing the keyboard to cover the input until I st ...

Looking to split the month and year input boxes when utilizing stripe version 7.2.0

Currently, I am utilizing ngx-stripe Version 7.2.0 to manage UI elements in Angular. I'm wondering if there is a method to split the Month and Year into separate text boxes within the UI of Angular 7 instead of having them combined into one field? ...

What is the best approach to upgrade this React Native code from version 0.59.10 to version 0.72.5?

I am encountering an issue with the initialRouteName: 'Notifications' property, while working on my React Native code. Despite trying various solutions, I have not been successful in resolving it. As a newcomer to React Native, any assistance wou ...

What could be the root of the error message "Outlet is not activated"?

As I work on developing a workflow with 4 steps in my web application, I encounter an issue when navigating from step 1 to step 4 and then back to step 1 without reloading the application. Upon repeating the path from step 1 to step 4 for the second time, ...

Issues with installing dependencies in Angular 2 through npm

While developing my Angular 2 application locally, everything was working smoothly. However, when I tried to deploy it to the server without the node_module folder and then did a npm install followed by a build, my app just kept showing "Loading..." withou ...

Pass a photo along with additional characteristics to the post endpoint in the API

Using the code snippet below, I am able to send an image to a post method and save it as a BLOB in the database successfully: Angular Code: public postUploadedFile(file:any){ this.formData = new FormData(); this.formData.append('file',fi ...

Problems with the zoom functionality for images on canvas within Angular

Encountering a challenge with zooming in and out of an image displayed on canvas. The goal is to enable users to draw rectangles on the image, which is currently functioning well. However, implementing zoom functionality has presented the following issue: ...

Click on the photo and drag your mouse outside of it to zoom out [Angular2]

HTML <div class="zoomPhoto" *ngIf="zoomed" (click)="unZoomPhoto()"> <img src="{{currentPhoto}}" [style.margin-left.px]="-(zoomedPhotoWidth/2)" [style.margin-top.px]="-(zoomedPhotoHeight/2)" #photo /> </div> CSS .zoomPhoto{ backg ...

Having difficulty accessing a function within the SignalR connection function

I am currently facing an issue while trying to access a specific function within a SignalR connection function. Below is the code snippet showcasing the entire script for better understanding: $(function() { var chat = $.connection.chatHub; chat.c ...

Guide on retrieving an ArrayList() from intricate function in Angular

Simplicity is the key to my question. Let's take a look at this Angular method: getAllOrdersHeaders(){ this.getAllOrdersIds().subscribe(idList=>{ idList.forEach(id=>{ this.ordersCollection.doc(id).collection('metadata&apo ...

What is the best approach to integrating payment solutions into a React Native application running on version 0

Seeking advice on integrating payment systems in React Native 0.70. Previously utilized react-native-credit-card-input and react-native-credit-card-input-plus with earlier versions, but they are now incompatible. ...

MediaRecorder is not compatible with Protractor unit tests in Angular

Currently working on an Angular 11 project that includes unit tests. Just introduced a MediaRecorder into the project, but now none of the tests are functioning properly. The test compilation is throwing this exception: error TS2304: Cannot find name &apos ...

The Firebase database is experiencing difficulties fetching the data

Having an issue with my component. Struggling to retrieve data from Firebase. Can someone spot the error in the code below? import { Component, OnInit, Input, ViewChild } from '@angular/core'; import { AngularFireDatabase, FirebaseListObservable ...