Home > Software engineering >  Populate React dropdown with Axios response
Populate React dropdown with Axios response

Time:11-24

I've made a drop down in React and I want to populate it with the response coming from an Axios GET call to an API.

My API call is on a different script.

import DIDataService from "../services/DIService";
import React from "react";

const PresetDropDown= () => {
  const [presets, setPresets] = React.useState([]);

  React.useEffect(() => {
    async function getPresets() {
      const response = DIDataService.findAllPresets()
      .catch((e) => {
        console.log(e);
      });
      setPresets(response);
    }
    getPresets();
  }, []);

  return (
    <select>
      {presets.map(item => (
        <option
          key={item.value}
          value={item.value}
        >
          {item.label}
        </option>
      ))}
    </select>
  );
}

export default PresetDropDown;

But I'm getting a nasty error when trying to map the options for the select:

Uncaught TypeError: presets.map is not a function
    at PresetDropDown (PresetDropDown.js:19)
    at renderWithHooks (react-dom.development.js:14985)
    at updateFunctionComponent (react-dom.development.js:17356)
    at beginWork (react-dom.development.js:19063)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at beginWork$1 (react-dom.development.js:23964)
    at performUnitOfWork (react-dom.development.js:22776)
    at workLoopSync (react-dom.development.js:22707)
    at renderRootSync (react-dom.development.js:22670)
    at performSyncWorkOnRoot (react-dom.development.js:22293)
    at react-dom.development.js:11327
    at unstable_runWithPriority (scheduler.development.js:646)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
    at flushSyncCallbackQueue (react-dom.development.js:11309)
    at flushPassiveEffectsImpl (react-dom.development.js:23620)
    at unstable_runWithPriority (scheduler.development.js:646)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushPassiveEffects (react-dom.development.js:23447)
    at react-dom.development.js:23324
    at workLoop (scheduler.development.js:590)
    at flushWork (scheduler.development.js:545)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:157)

The JSON being returned by the API is an array:

[
{
"presetName": "DEFAULT",
"presetValue": "project = BD",
"id": 200001348
},
{
"presetName": "FirstTest",
"presetValue": "key = BD-1038",
"id": 200001349
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001350
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001351
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001352
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001353
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001354
},
{
"presetName": "ThirdTest",
"presetValue": "key = BD-1039",
"id": 200001355
}
]

How do I map the JSON that I got from Axios to the drop down options?

UPDATE 1:

I changed my useEffects hook to use the response like so:

  React.useEffect(() => {
    async function getPresets() {
      DIDataService.findAllPresets()
      .then((response) => {
        setPresets(response.data.map(({ presetName, presetValue }) => ({ label: presetName, value: presetValue })));
      })
      .catch((e) => {
        console.log(e);
      });
    }
    getPresets();
  }, []);

CodePudding user response:

DIDataService.findAllPresets() seems to return a promise either await or call the then():

DIDataService.findAllPresets().then(res => setPresets(res))
//Or
const res = await DIDataService.findAllPresets();
setPresets(res)

Also, since you said axios,I think it return's an axios response, so you have to get data:

DIDataService.findAllPresets().then(({data}) => setPresets(data))
//Or
const { data } = await DIDataService.findAllPresets()
setPresets(data)

CodePudding user response:

React.useEffect(() => {
    async function getPresets() {
      // here findAllPresets will return a promise, not the data you want to manipulate
      const response = DIDataService.findAllPresets()
      .catch((e) => {
        console.log(e);
      });
      setPresets(response);
    }
    getPresets();
  }, []);

here's a right sample

React.useEffect(() => {
    async function getPresets() {
      const response = await DIDataService.findAllPresets()
      .catch((e) => {
        console.log(e);
      });
      setPresets(response);
    }
    getPresets();
  }, []);

or

React.useEffect(() => {
    function getPresets() {
      DIDataService.findAllPresets()
      .then(res => {
        setPresets(res)
      })
      .catch((e) => {
        console.log(e);
      });
    }
    getPresets();
  }, []);
  • Related