Tips on displaying a spinner only when data is retrieved from an Http service

How can I ensure that a spinner is only shown during an HTTP service call and dismissed when my component receives data?

To address this issue, I implemented a cache service to store data fetched from the HTTP service for future use. However, I want to show the spinner only during the initial HTTP call and not when data is fetched from the cache.

While the service functions correctly, the spinner continues to display even when data is retrieved from the cache. Is there a way to trigger the spinner display only during HTTP calls and not when fetching cached data?

In the code snippet below, the presentLoading() method gets called in ngOnInit, so it runs every time. How can I modify it to only execute when fetching data from the cache?


    ngOnInit() {
       this.presentLoading();
       this.CategoryCtrl();
     }

     CategoryCtrl() {
       this.serverService.getReviewsCategory(this.id)
       .subscribe((data) => {
         this.category_sources = data['value'];
         this.stopLoading();
       });
     }

     async presentLoading() {
       const loadingController = this.loadingController;

       const loadingElement = await loadingController.create({
         spinner: 'crescent',
       });
       return await loadingElement.present()
     }

     async stopLoading() {
       return await this.loadingController.dismiss();
     }

   }

EDIT1: This is the CacheService:


    import { Injectable } from '@angular/core';

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

      constructor() { }

      private _cache = {};

      isCached(url: string) {
        return this._cache[url];
      }

      getData(url: string) {
        return this._cache[url];
      }

      setData(url) {
        return (data) => {
          if (data && (data instanceof Error) === false) {
            this._cache[url] = data;
          };
        }
      }

      reset() {
        this._cache = {};
      }
    }

This is the server service's method:



     getReviewsCategory(cat_id) : Observable<any> {
      if (this._c.isCached(url)) {
            return of(this._c.getData(url));
          }else{
            var modeapp = window.sessionStorage.modeapp;
            var typemodeapp = typeof(window.sessionStorage.modeapp);
            if (modeapp === "online") {
              let promise = new Promise ((resolve, reject) => {
                this.httpNative.get(url, {}, {}).
                then((data) => {
                  let mydata = JSON.parse(data.data);
                  console.log("Data from HTTP: ");
                  console.log(mydata);
                  resolve(mydata);
                }, (error) => {
                  console.log("error in HTTP");
                  reject(error.error);
               }
              );
            });
              var observable = from(promise);
          }
        }
        return observable
        .pipe(
          tap(this._c.setData(url))
        );

Answer №1

It appears that you are returning an observable from the service. To address any issues, you can attempt the following solution.

     CategoryCtrl() {
       this.serverService.getReviewsCategory(this.id)
       .subscribe((data) => {
         this.category_sources = data['value'];
         this.stopLoading();
       },
       (error) => console.log(error),
       () => this.stopLoading(); // This will always be executed
     );}

Documentation: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-subscribe

On a related note, it is worth noting that the problem could be stemming from how you are calling .dismiss() on the object. Ensure you are invoking dismiss on the correct instance of the element and not the object itself.

let loadingElement: Loading = null;

async presentLoading() {
   const loadingController = this.loadingController;
   this.loadingElement = await loadingController.create({
     spinner: 'crescent',
   });
   return await loadingElement.present()
}

async stopLoading() {
   return await this.loadingElement.dismiss();
}

Answer №2

If you want to manage http requests in Angular, one effective way is to use an HttpInterceptor class. This allows you to intercept all outgoing HTTP calls and perform actions like displaying a spinner while waiting for a response.

The basic structure of using an HttpInterceptor is as follows:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Display spinner
    return next.handle(req).pipe(
        map((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // Hide spinner
            }
            return event;
        })
    );

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

Tracking dynamic collections in AngularJS ng-repeat using track by

I am attempting to utilize ng-repeat with the result of a function call, like this: <body ng-init='a = [1, 2, 3]'> <div ng-repeat='item in f(a) track by item[0]'>{{item}}</div> </body> where the function f is ...

Calculating the sum of values in a JSON array using a specific parameter in Typescript

A flat JSON array contains repetitive identifier, categoryId, and category: data: [ { "identifier": "data", "categoryId": "1", "category": "Baked goods", "product": "Aunt Hattie's", "price": "375" } ...

Vue-Router functions only on specific routes

While my vue-router correctly routes the URL for all menu buttons, it's not displaying each Vue component properly. You can see a demonstration here. Here is a snippet of my HTML (using Vuefy) <div class="navbar-start"> <a ...

Dynamically change the fill color of an SVG using styled-components

I've been attempting to target the fill property of my SVG using CSS in styled-components without any luck. Here is my SVG: <svg width="65" height="19" viewBox="0 0 65 19" fill="none" xmlns="http://www. ...

Choose the camera when utilizing the navigate.getUserMedia() function

I am currently utilizing the navigate.getUserMedia() method to record video on my mobile device and perform additional processing on it. However, at the moment, it is only capturing video using the front camera. How can I make it switch to the rear facing ...

Shift the Kid Element to an Alternate Holder

Currently, I am working on a project in Angular version 10. Within this app, there is a component that can be shared and will utilize the provided content through ng-content. Typically, this content will consist of a list of items such as divs or buttons. ...

Getting rid of quotes in a JSON result

My unique code snippet Retrieve data = Array[2] : 0:object id : "1" lat : "76.23" long:"21.92" 1:object id:"2" lat:"10.23" long:"12.92" var newCoords=[]; for(_i = 0; _i < ...

The current directory does not belong to a Cordova project

Upon executing ionic cordova run browser --verbose within the main directory of my Ionic4 project, I encounter the error message "Current working directory is not a Cordova-based project." as shown below. I've observed that the command generates a "w ...

The angular content is not scrolling

I have a basic angular content window that contains an adjustable group of settings values. When the window is collapsed, the fxLayout collapses properly, but I am having difficulty scrolling vertically. I have attempted to use overflow-y and just overflow ...

Creating an Angular 2 component library that is compatible with both webpack.js and system.js: A guide

This is my first venture into creating an Angular 2 library. So far, it consists of a collection of components. I am aiming to make this library compatible with both Webpack and SystemJS. I have successfully written the code for the first component to be c ...

Enhancing nouislider jQuery slider with tick marks

I have integrated the noUIslider plugin () into one of my projects. I am seeking guidance on how to display tick marks below each value on the slider. This is the current initialization code for the slider: $slider.noUiSlider({ 'start': sta ...

Headers cannot be modified after they have been sent to the client in Node.js and Angular

I am working on developing login and registration services using Nodejs Express. Every time I make a request in postman, I consistently encounter the same error: https://i.stack.imgur.com/QZTpt.png Interestingly, I receive a response in postman (register ...

What is the best way to assign an identifier to a variable in this scenario?

script.js $('a').click(function(){ var page = $(this).attr('href'); $("#content").load(page); return false; }); main.html <nav> <a href="home.html">Home</a> <a href="about.html">About</a> < ...

Reset jQuery validation when a button is clicked

I need assistance with a form validation issue. I am using jQuery validation methods to validate the controls on my form. However, I am facing difficulties in clearing the validation when clicking on 'cancel'. Below is the code snippet: <scr ...

retrieving and presenting information stored in a Firebase repository

I am currently working on retrieving data from a firebase database and storing it in an array called courses that I have declared within my class. Here's the code I have so far: import { AngularFireDatabase, AngularFireList } from 'angularfire2 ...

Observing the innerHTML of a Vue component

Currently, I am utilizing an npm package called vue3-markdown-it to display markdown within some of my content. When the component renders, I need to access its innerHTML and make customized modifications before displaying it in my div. However, there is ...

How can we use PHP and jQuery to open a simple modal with data?

Here is a basic modal setup: <div id="info" style="display: none;"> <h3 class="title">User Information</h3> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td width="50%" align="right ...

Retrieve a Play Scala variable in the $scope of an AngularJS application

After trying various methods recommended on StackOverflow, I am still struggling to retrieve a Play Scala variable within my Javascript $scope. The line of initialization in an HTML file is as follows: @(playVariable: String)(implicit request: play.api.mv ...

What is the sequence in which Jest executes its tests?

A fascinating challenge I've taken on involves testing a card game created in JavaScript using Jest. Currently, I have developed two tests: one to verify the creation of a 52-card deck and another to confirm that the player is dealt two cards at the ...

Displaying numerous Google maps on a single webpage featuring distinct collections of location markers

Currently, I am utilizing the Google Maps API to showcase two distinct Google maps on a single page. Each map comes with its own set of unique markers that are dynamically generated via Wordpress from various custom post types. While one map is successful ...