Skip to content Skip to sidebar Skip to footer

How To Call An Api Every Minute For A Dashboard In React

I've made a dashboard in React. It has no active updating, no buttons, fields or drop-downs. It will be deployed on a wall TV for viewing. All panels (9 total) are updated through

Solution 1:

Move the data fetch logic into a seperate function and invoke that function using setInterval in componentDidMount method as shown below.

componentDidMount() {
    this.loadData()
    setInterval(this.loadData, 30000);
  }

  asyncloadData() {
     try {
        const res = awaitfetch('https://api.apijson.com/...');
        const blocks = await res.json();
        const dataPanelone = blocks.panelone;
        const dataPaneltwo = blocks.paneltwo;

        this.setState({
           panelone: dataPanelone,
           paneltwo: dataPaneltwo,
        })
    } catch (e) {
        console.log(e);
    }
  }

Below is a working example

https://codesandbox.io/s/qvzj6005w

Solution 2:

In order to use await, the function directly enclosing it needs to be async. According to you if you want to use setInterval inside componentDidMount, adding async to the inner function will solve the issue. Here is the code,

asynccomponentDidMount() {
          try {
            setInterval(async () => {
              const res = awaitfetch('https://api.apijson.com/...');
              const blocks = await res.json();
              const dataPanelone = blocks.panelone;
              const dataPaneltwo = blocks.paneltwo;

              this.setState({
                panelone: dataPanelone,
                paneltwo: dataPaneltwo,
              })
            }, 30000);
          } catch(e) {
            console.log(e);
          }
    }

Also instead of using setInterval globally, you should consider using react-timer-mixin. https://facebook.github.io/react-native/docs/timers.html#timermixin

Solution 3:

I figured I'd chime in with a slightly revised approach that uses recursion via a setTimeout call within the function block. Works the same...maybe slightly cleaner to have the function call itself from within, instead of doing this elsewhere in your code?

This article explains the reasoning in a bit more depth...but I've been using this approach for several dashboards at work - does the job!

Would look something like this:

classMyComponentextendsReact.Component//create the instance for your interval
intervalID;
constructor(props) {
    super(props);
    this.state = {
        data: [],
        loading: false,
        loadingMap: false,

        //call in didMount...componentDidMount() {
          this.getTheData()
        }

 getTheData() {
 //set a loading state - good practice so you add a loading spinner or somethingthis.setState({loading: true}), () => {
 //call an anonymous function and do your data fetching, then your setState for the data, and set loading back to falsethis.setState({
       data: fetchedData,
       loading: false
       )}     }
 //Then call the function again with setTimeout, it will keep running at the specified //interval...5 minutes in this casethis.intervalID = setTimeout(
              this.getTheData.bind(this),
              300000
            );

          }
        }
        //Important! Be sure to clear the interval when the component unmounts! Your app might crash without this, or create memory leaks!componentWillUnmount() {
          clearTimeout(this.intervalID);
        }

Sorry if the formatting got a little off. Haven't tried this with Hooks yet but I think you'd have a similar implementation in a useEffect call? Has anyone done that yet?

Solution 4:

I have seen around a lot of complications about this. No need to have it in the lifecycles or in state or promisses. In here, the service api is just a simple axios api call

This is my full implementation as I use it with context api(omitting some private code). In my case I just care about the status response in the api since I know what I need to change. But the api can be really anything you need for/from data-wise.'

exportclassMyContextApiComponent ..... {
    private timeout: ReturnType<typeofsetInterval> | undefined
    ...
    ...
    ...
    public statsPolling = (S_UUID: string) => {
        if (!this.timeout) {
            this.timeout = setInterval( () => { 
                this.statsPolling(S_UUID)
            }, 3000)
        }

        this.state.api.StatisticsService.statsPolling(S_UUID)
            .then(res => {
                if (res.hasDescStats) {
                    clearInterval(this.timeout)
                    
                    this.setState(prevState => ({
                        ...prevState,
                        ...
                        ...
                    }))
                }
            })
            .catch(e =>console.warn('', e))
    }
   ...
   ...
}

/// in another file in service is the api call itself with axios just checking on the server reply statusexportclassStatistics implements IStatistics {
    public statsPolling: StatsPolling = asyncS_UUID => {
        return axios
            .get<{ hasDescStats: boolean }>(`/v2/api/polling?query=${S_UUID}`)
            .then(res => {
                if (res.status === 200) {
                    return { hasDescStats: true }
                } else {
                    return { hasDescStats: false }
                }
            })
    }
}

Solution 5:

Answer

You can create a function for the componentDidMount code.

import React, { Component } from'react';

import Panelone from'./Components/Panelone';
import Paneltwo from'./Components/Paneltwo';

classApp extends Component {

  state = {
      panelone: [],
      paneltwo: []
    }
code = async () => {
try {
        const res = await fetch('https://api.apijson.com/...');
        const blocks = await res.json();
        const dataPanelone = blocks.panelone;
        const dataPaneltwo = blocks.paneltwo;

        this.setState({
          panelone: dataPanelone,
          paneltwo: dataPaneltwo,
        })
      } catch(e) {
        console.log(e);
      }
}

 componentDidMount() {
    
      }

  render () {
    return (
      <div className="App">
        <div className="wrapper">
          <Panelone panelone={this.state} />
          <Paneltwo paneltwo={this.state} />
        </div>
      </div>
    );
  }
}

export default App;

then make a componentDidUpdate

import React, { Component } from'react';

import Panelone from'./Components/Panelone';
import Paneltwo from'./Components/Paneltwo';

classApp extends Component {

  state = {
      panelone: [],
      paneltwo: []
    }
code = async () => {
try {
        const res = await fetch('https://api.apijson.com/...');
        const blocks = await res.json();
        const dataPanelone = blocks.panelone;
        const dataPaneltwo = blocks.paneltwo;

        this.setState({
          panelone: dataPanelone,
          paneltwo: dataPaneltwo,
        })
      } catch(e) {
        console.log(e);
      }
}

 componentDidMount() {
    this.code()    
 }
 componentDidUpdate(){
this.code()
}
  render () {
    return (
      <div className="App">
        <div className="wrapper">
          <Panelone panelone={this.state} />
          <Paneltwo paneltwo={this.state} />
        </div>
      </div>
    );
  }
}

export default App;

Post a Comment for "How To Call An Api Every Minute For A Dashboard In React"