JedWatson / react-select

The Select Component for React.js
https://react-select.com/
MIT License
27.49k stars 4.12k forks source link

There are no default options, but when i start typing ,then options are shown #5751

Open ObaidAshiq opened 11 months ago

ObaidAshiq commented 11 months ago

Disclaimer

I am dynamicallly generating multiple DynamcMultiSelect components using map function on a array which I am fetching from API. Bascically I have a ADD button which creates a modal which has a dropdown, when a user select a value from it I am fetching an array from the backend, which will be used to make multiple DynamicMultiSelectComponents which use react-select. But when I click on any of the i am getting no Options, but when I type something I am getting all the values,

DynamicMultiSelect Component `

import { useState } from "react";
import AsyncSelect from "react-select/async";
import { toast } from "react-toastify";
import ToastMsg from "../UI/ToastMsg";

const DynamicMultiSelect = ({ fieldNames, selectedDataModel, fieldName }) => {
const [options, setOptions] = useState({});

const handleChange = (selectedOption)=>{
     console.log('HandleChange',selectedOption)
}
const loadOptions = async (searchValue, callback) => {
try {
  const response = await fetch(
    process.env.NEXT_PUBLIC_API_DOMAIN + "/nautobot/charts/filterValues",
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        dataModel: selectedDataModel,
        filterKey: fieldName,

      }),
    }
  );
  const data = await response.json();
  console.log('Firldname', fieldName, '==========',data.values)
  const loadedOptions  = data?.values?.map((option) => ({
    label: option.toString(),
    value: option.toString(),
  }));

  const filteredOptions = loadedOptions.filter((option)=>option.label.toLowerCase().includes(searchValue.toLowerCase()));
//   console.log(loadedOptions)
  callback(loadedOptions)
  setOptions(loadedOptions );
} catch (error) {
  console.error("Error fetching data:", error);
  const errorToast = () => {
    toast.error(<ToastMsg message={error} />, {
      hideProgressBar: true,
      progress: undefined,
    });
  };
  errorToast();
}
};
return (
 <div>
   <label>
    {/* {console.log('Options',options)} */}
    {fieldName}
    <AsyncSelect
      loadOptions={loadOptions}
      defaultOptions
      isMulti
      onChange={handleChange}
      //   defaultOptions={options}
    //   cacheOptions
      placeholder={`Select ${fieldName}`}
    />
  </label>
 </div>
);
};

export default DynamicMultiSelect;`

Creating this component

` {nonNumberedFields.map((fieldName)=> (

  ))
 }`

Images Scene 1 image

Scene 2 image

Scene 3 image

Scene 4 image

ObaidAshiq commented 11 months ago

I switched the use from AsyncSelect to Select and from loadOptions props to useEffect

 `import { useState,useEffect } from "react";
 // import AsyncSelect from "react-select/async";
 import Select from 'react-select';

import { toast } from "react-toastify";
import ToastMsg from "../UI/ToastMsg";

 const DynamicMultiSelect = ({ fieldNames, selectedDataModel, fieldName }) => {
 const [options, setOptions] = useState({});

//Used useEffect to fetch options when the component mounts for the first time, i.e. everytime the map was used
 useEffect(() => {
  loadOptions()
 }, [])

 const handleChange = (selectedOption)=>{
console.log('HandleChange',selectedOption)
}
 const loadOptions = async (searchValue,callback) => {
console.log(searchValue)
try {
  const response = await fetch(
    process.env.NEXT_PUBLIC_API_DOMAIN + "/nautobot/charts/filterValues",
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        dataModel: selectedDataModel,
        filterKey: fieldName,

      }),
    }
  );
  const data = await response.json();
  console.log('Firldname', fieldName, '==========',data.values)
  const loadedOptions  = data?.values?.map((option) => ({
    label: option.toString(),
    value: option.toString(),
  }));

  setOptions(loadedOptions );
} catch (error) {
  console.error("Error fetching data:", error);
  const errorToast = () => {
    toast.error(<ToastMsg message={error} />, {
      hideProgressBar: true,
      progress: undefined,
    });
  };
  errorToast();
  }
};
  return (
<div>
  <label>
    {/* {console.log('Options',options)} */}
    {fieldName}
    <Select
    options={options}
      isMulti
      onChange={handleChange}
      placeholder={`Select ${fieldName}`}
    />
  </label>
</div>
 );
};

export default DynamicMultiSelect;`