Steps for displaying mat-spinner for every row in mat-table in Angular 6

I've implemented a mat-table to display a list of executing Jobs. Alongside each row, there are two buttons (Stop and Re-Run) that users can interact with. What I'm trying to achieve is to have a mat-spinner only show up when a Job is running or when the user clicks on the Re-Run Button. Although I have set up the spinner, it currently displays for all rows when I click on the Re-Run Button. How can I make sure it appears only for the specific row that was clicked?

My HTML code:

 <!-- Code for Stop and Re-Run Buttons -->
        <ng-container matColumnDef="actions">
            <mat-header-cell *matHeaderCellDef> </mat-header-cell>
            <mat-cell *matCellDef="let element; let index = index">
                <button
                    mat-icon-button
                    (click)="stop_exec_job(element)"
                    matTooltip="Stop Executing the Job"
                    [disabled]="element.status == 'Completed'"
                >
                    <i class="material-icons" style="color:red"> stop </i>
                </button>
                <button
                    mat-icon-button
                    (click)="re_run_job(element)"
                    matTooltip="Re-Run the Job"
                    [disabled]="
                        element.status == 'Running' ||
                        element.status == 'Pending'
                    "
                >
                    <i class="material-icons" style="color:green">
                        cached
                    </i>
                </button>
            </mat-cell>
        </ng-container>
        <!-- Code for Spinner -->
        <ng-container matColumnDef="spinner">
            <mat-header-cell *matHeaderCellDef> </mat-header-cell>
            <mat-cell *matCellDef="let element">
                <div *ngIf="displaySpinner;else doNotShowSpinner">
                    <mat-spinner></mat-spinner>
                </div>
                <ng-template #doNotShowSpinner>

                </ng-template>
            </mat-cell>
        </ng-container>

        <mat-header-row
            *matHeaderRowDef="jobExecStatDisplayedColumns"
        ></mat-header-row>
        <mat-row
            *matRowDef="
                let row;
                columns: jobExecStatDisplayedColumns;
                let element
            "
            class="element-row"
        >
        </mat-row>

Typescript Code:

displaySpinner: boolean = false;

stop_exec_job(element) {
    if (element.status == "Running" || element.status == "Pending") {
        //Api to stop Job Execution
        this.recommendationService
            .stopJobExecution(element.jobId, "Cancelled")
            .subscribe(data => {
                this.executeJobStop = data;
            });
        this.displaySpinner = false;
        element.status = "Completed";
        this.snakbar.statusBar("Job Execution Stopped", "Sucess");
    } else {
        this.snakbar.statusBar("Job Failed to start", "Failure");
    }
}

re_run_job(element) {
    if (
        element.status == "Cancelled" ||
        element.status == "Completed" ||
        element.status == "Executed" ||
        element.status == "FINISHED"
    ) {
        //Api to Re-Run Job Execution
        this.recommendationService
            .stopJobExecution(element.jobId, "Running")
            .subscribe(data => {
                this.executeJobStop = data;
            });
        this.displaySpinner = true;
        element.status = "Running";
        this.snakbar.statusBar("Job Execution Started", "Sucess");
    } else {
        this.snakbar.statusBar("Job Failed to start", "Failure");
    }
}

The functionality of the stop and re-run button is working correctly. When clicking stop on a specific row, only that row's status changes. However, clicking run on one row triggers the spinner to appear for all rows, which is not the intended behavior.

Answer №1

The primary reason why the function stop_exec_job only updates the status of the clicked rows is because you are modifying the status of the element that is passed to the function.

In addition, your function re_run_job also changes the status, but the issue lies in using a single variable displaySpinner in your component to control the visibility of all spinners on each row.

To address this issue, consider adding an extra property to each element, where you can store the spinner status for individual rows (e.g., displaySpinner).

If the spinner's visibility depends on the element's status, you could modify your HTML to something like this (eliminating the need for the displaySpinner variable):

<div *ngIf="element.status === 'Pending' || element.status === 'Running'">
  <mat-spinner></mat-spinner>
</div>

Answer №2

The global property displaySpinner, used in the class, affects all rows when clicking Re-Run. This causes all rows to display the spinner as they are conditioned on the same property.

Instead of displaySpinner, consider using element.status.

Modify the following lines:

<div *ngIf="displaySpinner;else doNotShowSpinner">
    <mat-spinner></mat-spinner>
</div>

to the following:

<div *ngIf="element.status === 'Running';else doNotShowSpinner">
    <mat-spinner></mat-spinner>
</div>

Answer №3

Connect the spinner to the status of the element:

<!-- Code for Spinner -->
        <ng-container matColumnDef="spinner">
            <mat-header-cell *matHeaderCellDef> </mat-header-cell>
            <mat-cell *matCellDef="let element">
                <div *ngIf="element.status === 'Running'">
                    <mat-spinner></mat-spinner>
                </div>
                <ng-template #doNotShowSpinner>

                </ng-template>
            </mat-cell>
        </ng-container>

It is also advisable to define an enum for your statuses to enhance readability and maintain consistency.

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

Uploading a JSON file to myjson.com using a jQuery PUT request in Node.js

As a novice in javascript, I have successfully retrieved a JSON object from on my HTML page using AJAX with the following code: $.getJSON("https://api.myjson.com/bins/bjm28", function (data) { $.each(data, function (index, value) { console.log ...

Developing a type specifically for this function to operate on tuples of varying lengths

I am currently developing a parser combinator library and I am in need of creating a map function that can take N parsers in a tuple, along with a function that operates on those N arguments and returns a parser that parses into the return type specified b ...

Utilizing jQuery to retrieve data from a JSON object with a nested array

After making an API call to Google Translate, the following data was returned: { "data": { "detections": [ [ { "language": "en", "isReliable": false, "confidence": 0.051902372 } ] ] } } In order to access the "language" ...

Performing an AJAX call using the PUT method to update information in the

I am facing difficulties when trying to call my REST api from JavaScript, as I keep receiving either a Bad Request or an Unsupported Media Type error depending on my testing... Here is my Servlet code: /** * Update an existing frame * * @ ...

JavaScript: Efficient ways to extract necessary elements from an array

Currently, I am in the process of creating a tokenizer that constructs an abstract tree. My specific goal is to gather all the "text" elements from an array produced by this tokenizer. The output looks like this: { "error": false, "tokens": [ { ...

Is there a way to programmatically display a Chakra-UI Toast?

I'm currently struggling to programmatically display a Chakra-UI Toast using the Chakra-UI React.js component library. The Chakra-UI Toast documentation only provides examples of showing the toast based on a button click, but I'm looking to show ...

Unable to detect hover (etc) events after generating div elements with innerHTML method

After using the code below to generate some divs document.getElementById('container').innerHTML += '<div class="colorBox" id="box'+i+'"></div>'; I am encountering an issue with capturing hover events: $(".colorB ...

The category has been defined but remains inaccessible. What could be the reason for this limitation?

I've been utilizing this bson library along with the corresponding declaration found here. Within this library, there is a method called serialize():Buffer which returns a Buffer. When I execute the following code: let data:Buffer = this.serializer.s ...

Tips for locating the :before element's position with Javascript

I am currently working on an animation where I need to change the color of an element in the center once a small circle touches it. Despite trying to use the position() method, it does not work as intended because I am using a :before for animating the div ...

Users will not receive notifications or see highlighted mentions

Lately, I've been experimenting with Discord.js and Typescript and came across an issue while trying to create a simple command that pings the user. However, instead of pinging them, it only mentions their username. Below is the code snippet I'm ...

Master the art of applying z-index to PrimeNG dropdown menus

Currently using Angular 18 in combination with PrimeNG, I am facing an issue with a dropdown component being visually cut off by a table footer from PrimeNG. Despite attempting to adjust the z-index of various p-dropdown CSS classes, I have not been able t ...

Sequelize is incorrectly pointing to an invalid foreign key

There are two tables in my database, namely Transaction and Transaction Details. The recordId serves as a foreign key in the Transaction Details table. My goal is to query a specific Transaction based on its recordId and include all associated Transaction ...

Prolong the period of validity for OTPs in the Speakeasy Node library

Is there a way to extend the validity period of a token in the Speak Easy library? var secret = speakEasy.generateSecret({length: 20}); var token = speakEasy.totp({ secret: secret.base32, encoding: 'base32', ...

Building a continuous timer loop in Angular using RxJS that adapts to changing durations within an array's objects

I am experimenting with a scenario where I read the data, loop based on the duration. For example, starting with "Adam" first, play Adam for a 15-second timer, then move on to the next beginner "Andy" and play Andy for 15 seconds. Once we reach group "int ...

Ways to implement two functions within a single onclick event

Is it possible to call two functions with onclick event? <input id = "test" onclick="func1()"> Can I add another function as well? How would I go about doing that? ...

Running into an issue while attempting to generate functions in nodejs

I'm currently working on a function to authenticate a URL for a fetch request. However, when I attempt to call this function within the app.post callback, my Node.js server throws an error: "TypeError: authenticateUrl(...) is not a function". Does Nod ...

The error message "Property 'xy' is not found within the type '{}'. TS2339" indicates that the 'xy' property is not present

I've embarked on setting up a compact project utilizing react / typescript featuring the components below: App.tsx import React from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Styles ...

No data is being recorded in the Firestore database

This component in nextjs is designed to write data to a firestore database after the user clicks a button. Unfortunately, Firebase seems to be having trouble writing the data, even though the alert message following the supposed data dump is successful. I ...

Guide on efficiently removing a user entry from _User via Parse REST API

Having trouble removing a user from the _User table on parse.com and encountering an error. Confident in the correctness of my request syntax, yet receiving the following error: code: 206 error: "Parse::UserCannotBeAlteredWithoutSessionError" Believe th ...

Tips on setting an expiration time for verification codes in a Node.js environment

What is the best way to implement an expiration time for this verification code? I need it to be deleted from the database after 10 minutes. var fourcode = Math.floor(1000 + Math.random() * 9000); app.post("/sendforgetpassword", async (req, re ...