'Display loader before a react-apexchart is displayed

I want to display a loader till my chart is displayed.I have implemented the following code but it doesn't work.The loader should display as soon as "compare" button is clicked:

import React, { Component, Fragment,useState,useRef,createRef} from "react";
import Loader from "react-loader-spinner";
import RestAPI from "services/api";
import axios from "axios";
import Select from 'react-select';

import "d3-transition";

import {
    Button,
    Label,
    FormGroup,
    Form,
   
  } from "reactstrap";

import ReactApexChart from "react-apexcharts";


import "tippy.js/dist/tippy.css";
import "tippy.js/animations/scale.css";
class StackedAreaChart extends Component {
    constructor(props) {
      super(props);
      this.selectInputRef = React.createRef();
      this.selectInputRef1 = React.createRef();
      this.selectValue=this.selectValue.bind(this)
      this.clickEvent=this.clickEvent.bind(this)
      this.handleChange=this.handleChange.bind(this)
      this.onClear=this.onClear.bind(this)
      this.checkIfMounted=this.checkIfMounted.bind(this)
      this.state = {
        soptions:[],
        weights:[],
        years:[],
        loader:false,
        selectOptions: [],
        selectedValues:[],
        combinedList:[],
        yearsList:[],
        isLoaded:false,
        selectValue:"",
        series: []
      };
    }
    checkIfMounted() {
      console.log("mount")
      return this.selectInputRef1.current != null;
   }
 
    componentDidMount(){

    fetch("http://127.0.0.1:8000/api/getallvals/")
    .then(response =>  response.json())
    .then(json => {
        
        this.setState({
          
          soptions:json.topics,
          
               
        
          
        })            
    });
     
    }
    handleChange=(e)=>{
      const value = Array.isArray(e) ? e.map(s => s.value) : []
      this.state.selectedValues=value
      console.log("value is:",this.state.selectedValues)
    }
    selectValue(e){
        var selectValue=this.state.selectValue;
        var isDisplayed=this.state.isDisplayed;
        console.log("the val is:",e);
        console.log("the val is:",e.length);
        console.log("the val is:",e[0].value);
        this.setState({
          selectedValues:e,
          loader:false
        });
        

       
        console.log(this.state.selectedValues)
        
    }
    onClear() {
      //window.location.reload(false);
      //console.log(this.selectInputRef1.current)
      this.selectInputRef.current.select.clearValue();
    }
      //this.selectInputRef1.current.chart.destroy();}
  clickEvent(){
    
    console.log("in click event",this.state.selectedValues)
    var selectedValues=this.state.selectedValues;
    var {series}=this.state;
      fetch("http://127.0.0.1:8000/api/getallvals/"+'?'+selectedValues.join('&'))
        .then(response =>  response.json())
        .then(json => {
          
         
            series=[]
            for(let i=0;i<json.weights.length;i++){
              series=series.concat([{name:selectedValues[i],data:json.weights[i]}])
              //selectInputRef1.current.chart.publicMethods.updateOptions({})
            }
            this.setState({

              
            series: series,
            datalabels:{
                enabled:true
            },
            
            options:{
              stroke:{
                  curve:'smooth'
                },
                
          xaxis:{
              categories:json.years
          },
         
      },
          

              isLoaded:true,
              loader:false
            
              
                   
            
              
            })            
        });
     
      console.log("this state",series)
      
    }

  

    render() {
      const checkmount=this.checkIfMounted;
     
        var {options,isLoaded,loader,series,yeardata,soptions,weights,years}=this.state;
    if(isLoaded){
      return (
        
       
  <div id="chart" className="box" >
    <Form role="form" method="POST" >
                        
                        
                        <FormGroup>
                        <h2>Evolution of a value over Time
                        </h2>
                        <Label>Select a value</Label>
                        <Select ref={this.selectInputRef} name="selectOptions" isClearable isMulti placeholder="Select Option" options={soptions} 
                         
                         onChange={this.handleChange}/>
                                                    
                            
                            <br></br>
                        <Button onClick={ this.clickEvent }
                        >Compare</Button>
                        <Button onClick={this.onClear}>Reset</Button>
                       
                        <Loader type="puff" visible={loader} color="#00BFFF" height={100} width={100}></Loader>
                        </FormGroup>
              </Form>
   
      {checkmount?(
    <ReactApexChart ref={this.selectInputRef1} options={this.state.options} series={this.state.series} type="area" height={350} />):
    (<div>not yet loaded</div>)}
</div>)
    }
    else{
        return (
        
       
            <div id="chart">
              <Form role="form" method="POST" >
                                  
                                  
                                  <FormGroup>
                                  <h2>Evolution of a values over time
                        </h2>
                                  <Label>Select a value</Label>
                                  
                                                              
                                      <br></br>
                                      <Select ref={this.selectInputRef} name="selectOptions" isClearable isMulti placeholder="Select Option" options={soptions} 
                         
                         onChange={this.handleChange}/>
                                                    
                            
                            <br></br>
                        <Button onClick={this.clickEvent}>Compare</Button>
                        <Button onClick={this.onClear}>Reset</Button>   
                        <Loader type="puff" visible={false} color="#00BFFF" height={100} width={100}></Loader>


                                  </FormGroup>
                        </Form>
                        </div>) 
    }
    }
}
export default StackedAreaChart;

loader is the flag I have kept to decide whether or not to display loader but it still doesn't show up.Also I am disabling the loader when the page is not loaded



Solution 1:[1]

So what you want to do is, while you are fetching the data, the loader will be true. Once you fetch the data, the loader will be false.

So, inside clickEvent you can change

fetch("http://127.0.0.1:8000/api/getallvals/"+'?'+selectedValues.join('&'))
        .then(response =>  response.json())
        .then(json => {

to this:

this.setState({loader: true})
fetch("http://127.0.0.1:8000/api/getallvals/"+'?'+selectedValues.join('&'))
 .then(response =>  {
     this.setState({loader: false})
     response.json()
  })
 .then(json => {
...

Solution 2:[2]

React apexcharts has a mounted event that you can use, it is part of the chart-options: https://apexcharts.com/docs/options/chart/events/

You could have your own isLoaded state set to false initially, and when the apex-chart mounted event is fired you set your isLoaded state to true.

This way you can chose to display the loader when isLoaded is false, and hide it when it turns to true.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sinan Yaman
Solution 2 snubbus