0

I'm hoping to get some advice on how to best go about looping through my values to show one at a time and only display for 30 seconds then show the next value. I have the API call working and can get all of the data that is tied to [6] as you can see below, which are job name titles. So instead of showing all of the job names at once, I want to cycle through them and only show each one for 30 seconds or so. I have all of my data on other components as well to show line charts corresponding to that job. So my idea was cycle these job names, and then on each component that renders job data, have that change when the job name changes to correspond. Wanted to see if I could get some thoughts and suggestions on how to accomplish this!

Title.js

import { React, Component } from 'react';

let headers = {
  'QB-Realm-Hostname': 'XXXXXXXXX.quickbase.com',
  'User-Agent': 'FileService_Integration_V2.1',
  'Authorization': 'QB-USER-TOKEN XXXX_XXXX_XXXXXXXXXX',
  'Content-Type': 'application/json'
};

class Title extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: null
    };
  }

  componentDidMount() {
    this.fetchData();
  }    

  fetchData = () => {    
     let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"where": "{40.CT. 'In Progress'}","sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":1,"compareWithAppLocalTime":false}}

    fetch('https://api.quickbase.com/v1/records/query', {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(body)
    }).then(response => response.json())
      .then( data => this.setState({ data })
      );
    }

  render() {
    const { data } = this.state;

      if (data === null) return 'Loading Job Data...  ';

    return (
      <div className="Title">
          {Object.keys(data["data"]).map(item => (
            <div key = {item}>
              <h2>
                {data["data"][item][6].value}
              </h2>
            </div>
          ))}
      </div>
    )
  }
}

export default Title;

As you can see above, right now based on the body "options": "top":1, which will show only one value at a time, but I want to cycle them. If I change this to 0, then all values show up that are that field Id of 6.

I've also attached my application screenshot to show what I'm attempting to do, to show Job Name, and cycle that as well as corresponding line charts with that job's data every 30 seconds to show all jobs and their data.

Application Screenshot

I've thought of using a slider library like splide.js or glide.js to change each one, but just trying to begin with Title and try to tie the line charts based on what title is displaying.

Thanks in advance!

Alex
  • 131
  • 9

1 Answers1

1

You could use setInterval() to cause something to happen at regular intervals in your code. In this instance, you could use it to display only one of the returned records at a time. If you added a property to the state object for tracking the currently displayed index of your fetched data you could do something similar to this:

componentDidMount() {
  this.fetchData();
  setInterval(() => updateDisplay(), 30000)
}   

updateDisplay() {
  let index = this.state.currentIndex + 1;

  if(!this.state.data.data || index >= this.state.data.data.length) index = 0;
  
  this.setState({data: this.state.data, currentIndex: index});
}

render() {
  const { data, currentIndex } = this.state;

  if (data === null) return 'Loading Job Data...  ';

  return (
    <div className="Title">
        <div key = {item}>
          <h2>
            {data["data"][currentIndex]["6"].value}
          </h2>
        </div>
  </div>
  )
}

The above needs some cleaning up and you'd need to include currentIndex in the other parts of your class that set state but in principle it should work. Basically, only one of the returned records is rendered at a time instead of the whole list. The specific record being displayed is controlled by this.state.currentIndex and updateDisplay() is called every 30 seconds to update that index with some basic safeguards.

Nathan Hawe
  • 281
  • 3
  • 5
  • This looks exactly what i've been trying to figure out, displaying one at a time instead of all at once. I'll give this a shot. I noticed you removed ```{Object.keys(data["data"]).map(item => ())}```, is this not needed to map through each field value? – Alex May 28 '21 at 15:58
  • Been messing around with this and keep getting updateDisplay, or currentIndex is undefined. not sure what is going on or how to change the code – Alex Jun 01 '21 at 15:02