skip to Main Content

`

I’m trying to populate my select dropdown options with values that come from an API call as soon as the page loads. Currently, the options are only generated, how can i list options in select field. On page load, the options do not get filled and are empty. I’ve looked at other similar questions that suggest using the React-select package, but I’m looking for a way to do it with just react and I haven’t had any luck finding a solution. Please advise on how I can achieve this or where I can get help. I’ve attached my code below. Kind regards.`

abc.js

options &&
options.map((newoptions) => (

{newoptions.value}

))
}
}

 `useEffect(() => {
                fetch("http://localhost:4000/add-batch")
                .then(response => response.json())
                .then((res)=>{
                    const {data} = res;
                    setData(data);
                })
                .finally(() => {
                    
                  })
            console.log("Data", data);
            const results = []
                  
            data.map((value) => {
                    results.push({
                    key: value.id,
                    value: value.batchName,
                    });
                });
                setOptions([
                     results
                ])
               
    }, []);`

database

{
  "_id": {
    "$oid": "65b9dff4501239f11a2aedcb"
  },
  "programType": "Upskill Traningq",
  "batchName": "Upskill_03",
  "numberOfStudents": 20,
  "createdAt": {
    "$date": "2024-01-31T05:51:48.858Z"
  },
  "updatedAt": {
    "$date": "2024-01-31T05:51:48.858Z"
  },
  "__v": 0
}

how can i get the id value and batch name as dropdown list?

2

Answers


  1. I wrote a simple react component that lists the options you got from your api in a select field, hope its useful for you.

    import React, { useState, useEffect } from 'react';
    
    const YourComponent = () => {
      const [data, setData] = useState([]);
      const [options, setOptions] = useState([]);
    
      useEffect(() => {
        fetch("http://localhost:4000/add-batch")
          .then(response => response.json())
          .then((res) => {
            const { data } = res;
            setData(data);
          })
          .finally(() => {
            // Do something if needed after fetching data
          });
    
        const results = data.map((value) => ({
          value: value.id,
          label: value.batchName,
        }));
    
        setOptions(results);
      }, [data]);
    
      return (
        <div>
          <select>
            {options.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
      );
    };
    
    export default YourComponent;
    
    Login or Signup to reply.
  2. there are some errors in your code.
    Basically you can’t use async function inside useEffect like you did.

    Instead of

    useEffect(() => {
      const res = await fetch(URL)
      // stuff using res
    }, [])
    

    you need to wrap it into a function and call it inside the useEffect, like this:

    useEffect(() => {
      const asyncFunc = async () => {
        const res = await fetch(URL)
        // stuff using res
      }
      // then call it
      asyncFunc();
    }, [])
    

    beyond that, if you don’t need to store data into data local state for other reason than mapping the select option. you could store that into a local variable inside then function or after await and map the options using the local variable or directly using destructured data from the response (const {data} = res).

    Instead, if you need to use the response in other places rather than mapping the select option, you should call the setter setData(data) as you did, but point to it in other useEffect which has data as a dependency, like this:

    useEffect(() => {
      const asyncFunc = async () => {
        const res = await fetch(URL)
        const data = res.json();
        setData(data);
      }
      // then call it
      asyncFunc();
    }, [])
    
    
    useEffect(() => {
      if (data && data.length > 0) {
        setOption(data.map(// mapping as you wish);
      } 
    }, [data]);
    

    Your code doesn’t work properly because the setter of useState is not synchronous, instead they are scheduled. So when you call setOption from data (the useState, not the destructured one) you don’t have the desired value inside data, you will have it at the end of the method when the component will be rendered.

    I hope this will help you

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search