The loading spinner isn't appearing while the function is running

Having trouble displaying a loading spinner while a function is running. I've tried different methods, but the spinner just won't appear.

Here's the HTML snippet:

<div class="row pt-3" id="firstRow">
 <div class="col">
  <button class="btn btn-dark back-button">
   <fa name="upload"></fa>
   <span>Load .csv file</span>
  </button>
  <input type="file" #fileImportInput name="File Upload" class="txtFileUpload p-3" (change)="fileChangeListener($event)" accept=".csv" />
    <img class="spinner" *ngIf="loading" src="../../../assets/img/gif-spinner/Spin-2s-200px.gif" />
 </div>
</div>

This is part of the TypeScript code:

export class MotionAnalysisComponent implements OnInit {
loading = false;

 fileChangeListener($event: any): void {
   this.loading = true;

   let files = $event.srcElement.files;

   if (this.isCSVFile(files[0])) {
    let input = $event.target;
    let reader = new FileReader();
    reader.readAsText(input.files[0]);

    reader.onload = () => {
     let csvData = reader.result;
     let csvRecordsArray = (<string>csvData).split(/\r\n|\n/);
     this.csvRecords = this.getDataRecordsArrayFromCSVFile(csvRecordsArray, 4);
   };

   reader.onerror = function () {
    alert('Unable to read ' + input.files[0]);
   };
  } else {
    alert("Please import valid .csv file.");
    this.fileReset();
  }

   this.loading = false;

If I remove the "this.loading = false" line within the function, the spinner appears after the function has finished executing and stays visible. How can I instruct the HTML to display the spinner during the function execution?

Answer №1

In order to give the spinner enough time to initialize, you should execute the code asynchronously after marking loading as true. This can be accomplished by enclosing the code within a setTimeout callback function. Remember to reset the loading property at the end of this callback.

fileChangeListener($event) {
  this.loading = true;                    // Start by setting loading to true
  setTimeout(() => {                      // Utilize setTimeout for asynchronous execution
    let files = $event.srcElement.files;
    if (this.isCSVFile(files[0])) {
      ...
    } else {
      ...
    }
    this.loading = false;                 // Reset loading before exiting the callback
  }, 0);
}

For a demonstration, check out this stackblitz. Adjust the delay in setTimeout accordingly based on your specific needs (the example sets it to 0 ms).

Answer №2

My assumption is that

... a different section of the function...

represents a call to an observable or an asynchronous function, causing your

this.loading = false;

to be triggered immediately.

Without having full clarity on the content within that code block, it seems probable that you require a callback function that will execute once the asynchronous call has completed in order to properly set loading to false.

Answer №3

@Component({
  selector: 'm-selector',
  templateUrl: './selector.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush, <-- include this line
  styleUrls: ['./selector.component.scss']
})

implement a change detection method

next, within your constructor

constructor(
...,
private ref: ChangeDetectorRef <-- add this line
){ }

this allows you to manually request Angular to check for changes

you can then utilize it, like so:

this.loading = true
this.ref.markForCheck()

remember to call ref.markForCheck whenever you modify a variable impacting your HTML with *ngIf

this approach helps in reducing memory consumption by not constantly monitoring a specific variable

however, if your variable frequently changes, employing a listener is recommended

Answer №4

  1. To view debug information, it appears necessary to display the value of loading in your HTML:

    Load .csv file

    <p>loading {{ loading  }} </p>
    
    <img class="spinner" *ngIf="loading" 
        src="../../../assets/img/gif-spinner/Spin-2s-200px.gif" />
    </div>
    

If you notice that the value of loading updates correctly, then attempt to adjust the style accordingly:

img { 
     width: inherit; 
     height: inherit; 
     position: fixed; 
     top:0; 
     left:0; 
}
  1. Could there be a typo? Your closing div tag seems to be incorrect: /div>

UPDATE:

Try setting the src attribute of the image using a template expression:

HTML:

<img class="spinner" 
     *ngIf="loading" 
     [src]="imagePath"/>

TypeScript:

imagePath = '../../../assets/img/gif-spinner/Spin-2s-200px.gif;'

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

Anticipated outcome for absent callbacks in module API implementation

I am seeking advice on the expected behavior when developing a Node module API. It is becoming complicated in my module implementation to check if the caller has provided a callback before calling it. I am starting to believe that it may be the user's ...

Is there a way to track and detect alterations to an element using JavaScript or jQuery

Can I detect the addition of a specific CSS class to an element without having to create a new event? ...

Issues have been identified with the functionality of jQuery validation in MVC when applied to dynamically added elements

Although this issue has been addressed multiple times before, I am struggling to resolve it using the provided solutions. I am currently developing a basic library application. One of the features involves adding a copy of a book, which utilizes jQuery to ...

Using Jquery to target an element within the same DOM element and apply changes

My website platform doesn't assign any IDs or classes to the menus it generates, and uses nested lists for submenus. To make the submenus expand upon clicking, I created a jQuery script: $(function () { $(".wrapper ul li").click(function () { ...

Having trouble getting the ValidatorPipe to function properly in my nest.js application

Issue Description There is an issue with the current behavior where initializing a validation pipe for a request body does not reject invalid types as expected. Desired Outcome The expected behavior should be that when a user provides a value that does n ...

acquiring environmental variables in TypeScript for node applications

I am struggling with accessing process.env variables in my TypeScript pages. It seems to be a scope issue, which doesn't make sense to me as a beginner in TypeScript. To get my environment variables, I use a YAML file and attach them to the running p ...

Using Angular 2, perform an HTTP GET request to retrieve data from a JSON file located in the assets folder

Currently, I am working on fetching data from a JSON file located in the assets folder of my application. The framework I am using is Angular Material. For this purpose, I have created an account component which consists of the following files: account.co ...

How can React hook state be efficiently utilized in a debounced callback?

function Foo() { const [state, setState] = useState(0); const cb = useCallback(debounce(() => { console.log(state); }, 1000), []); return ...; } In the code snippet above, there is a potential issue where the state variable may become outda ...

Executing a jQuery AJAX request for a second time

Upon hitting the submit button for the first time, the codes work successfully. However, upon hitting the button for the second time with correct email and password values, nothing happens and the user cannot log in. I have identified that the issue lies w ...

Animate out Material UI element with zoom effect and then remove it from the

I'm currently working on a dynamic user interface that allows for adding and removing items dynamically. Each item has both an add and remove button, with a special animation effect using Zoom. While this works smoothly when adding new items, I encoun ...

Despite setting the date format in the Html Helper, the MVC still presents a validation error

When creating a razor view form to display the date field, I am using the following code: @Html.TextBoxFor(m => m.LectureDate, "{0:dd/MM/yyyy}") The desired date format is 21/04/2017, which is set by JQuery DatePicker. However, after setting the date ...

Encountering an issue when running npm build on server

I attempted to deploy my application on the hosting server and encountered the following error: Failed to compile. ./node_modules/next/dist/pages/_app.js Error: failed to process The global thread pool has not been initialized.: ThreadPoolBuildError { kin ...

When running npm install, an ERESOLVE error message may appear indicating that a resolution could

Upon executing npm install, I encounter the following error message: code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: @angular-devkit/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8baadb1b ...

Toggle button to create a fade in/out effect

Below is the HTML code snippet: <html> <head> <Script type = "text/javascript" src = "CprMdlrSrch.js"></Script> <link type="text/css"rel="stylesheet"href="CprMdlrSrch.css"/> </head> <body> <div id=" ...

An error has occurred in Angular: No routes were found that match the URL segment 'null'

I've recently developed a simple Angular page that extracts an ID (a guid) from the URL and uses it to make an API call. While I have successfully implemented similar pages in the past without any issues, this particular one is presenting challenges w ...

Having trouble retrieving the necessary data to generate a menu, the getStaticProps function is coming back as undefined

I'm currently working with Next.js 13 & Strapi, and my goal is to create a Menu component utilizing the getStaticProps function. To achieve this, I've implemented a Layout component within the _app.js file, and nested a Menu component inside the ...

Unable to retrieve the length of HTMLCollection

I've been having an issue with accessing all the dynamically created list elements (<li>) on my page using getElementsByTagName. The console keeps showing that the length of my li array is 0. Despite going through documentation and examples rel ...

Having trouble with Django's submit POST method for creating objects

Latest Updates: I have successfully implemented a feature where the page does not reload upon clicking the submit button. To achieve this, I filled out the form and inspected the page source code. The form structure was as follows: https://i.sstatic.net/ ...

Strategies for efficiently managing multiple subscriptions in an Angular form using minimal code and best practices

I am currently working on an Angular form that includes multiple select options managed by Subscriptions. However, I find myself writing a lot of code for each Subscription and would like to improve this process. Could someone provide some best practices ...

The term 'Component' is not a valid JSX component that can be used

'Component' is causing issues as a JSX component The error appears to be within the _app.tsx file of my Next.js project. I've been struggling with this problem since yesterday, encountered it during deployment on Vercel for my Next.js TypeS ...