简体   繁体   中英

How to make a dynamic progressbar with data received from an api

I have an api which sents score if someone does the math, chemistry or physics correct. The api is sends a response like this

{
  "scores": {
    "maths": 28,
    "chemistry": 9,
    "physics": 26,
  }
}

So if a person has done a problem then it'd post the answer and we get the score from the api. now I want is to have the scores show in kind of a progressbar. This is how I have coded my textarea and their functions and progressbar

export default class Science extends Component {
  constructor(props) {
    super(props);
    this.state = {
      snippetDescription: "",
      scoredata: [],
    };
  }
render{
 return(
  <>
    <textarea
              class="textareaclass"
              placeholder="Enter your text here"
              onChange={snippetDescription =>
                this.setState({ snippetDescription })
              }
            ></textarea>
    <Button
               className="btn savebtn"
               onClick={() => this.scoreanalysis({ ...this.state })}
               >
               Analyse
    </Button>
  </>
)}

this is the function where we will fetch the api and store the score for progressbar

  scoreanalysis = snippetDescription => {
    fetch("/api/marksapi/:", {
      method: "POST",
      body: JSON.stringify({
        snippetdesc: "snippetDescription"
      }),
      headers: {
        "Content-type": "application/json; charset=UTF-8"
      }
    })
      .then(response => response.json())
      .then(textdata => {
            this.setState({
            scoredata: textdata.scores,  //Is this how I save the scores in scoredata to later use in the progressbar?
          });
        },
        error => {
          console.log(error);
        }
      );
  };

The problem is I have not done much work in api so how do I store the values of maths, chemistry and physics in the scoredata state variable and access it to make the progressbar dynamic.

This is the progressbar I have made so far, not working obviously because I believe, fetching from the api wasn't correct so can anyone please show me where it's wrong and correct me.

    <div class="progress">
              <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100"
                          progressbar current="{scoredata.math}">
                          {scoredata.math}
                          <span class="sr-only">10% Complete</span>
              </div>
        </div>

I did this for a loading bar for an upload progress. I'm using bootstrap so I used their progress bar element :

<div class="progress">
  <div class="progress-bar" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>

But as you mentioned, you wanted this to be dynamic. So what you want is for when the progress bar component loads, you want it to make the API call and pass a callback function to modify the state to that value which you can plug into the progress bar.

So using my Bootstrap example, the progress bar might now look like this:

<div class="progress">
  <div class="progress-bar" role="progressbar" style={{width: uploadProgress + "%"}} aria-valuenow={uploadProgress} aria-valuemin="0" aria-valuemax="100"></div>
</div>

So when you load in this component, run a function (when the component mounts) that makes your API call, but pass in a callback function to update uploadProgress .

I'm using React Hooks (I'd highly recommend them) and here's how I set up uploadProgress :

const uploadProgress = useSelector(state => state.uploadProgress);

so I'm making a call to the state. This state is updated by the API function.

So to summarise:

  1. Make your API results run a function (send an action to an actionCreator) to update the state.
  2. Access this state in your progress bar component
  3. Use that state value as the value for your progress bar(s)

Let me know if you've got any questions - I am new to this myself but that's how I manged to do it and it works pretty well!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM