-2

I am attempting to populate drop down list dynamically. The list contains of states that are available in database . I am not supposed to add all 50 states, just the ones in the database , hence why this has to be dynamic.

This is not working because there is no 'add' function available to 'dropdown' element. Here is the error:

Project-fields.js:104 Uncaught (in promise) TypeError: e.add is not a function

The error is pointing to the line 'dropdown.add(options);'

This is the JSON object I receive upon fetch():

STATES: [{"_id":"Virginia","name":"Virginia","abbreviation":"VN","__v":0},{"_id":"North Carolina","name":"North Carolina","abbreviation":"NC","__v":0},{"_id":"Texas","name":"Texas","abbreviation":"TX","__v":0},{"_id":"Louisiana","name":"Louisiana","abbreviation":"LA","__v":0},{"_id":"5f1ef364691bf8c340104c18","name":"California","abbreviation":"CA"}

My Code :

function StateSelect({ values, initial }) {

 async function fetchStates(){
        let dropdown = document.getElementById('select');
        dropdown.length = 0;
        .then(
            function(response){
                if(response.status !== 200)
                {
                  console.warn('State Object Not Fetched' + response.status);
                  return;
                }

                response.json().then(function(data){
                    
                    console.log(`STATES: ${JSON.stringify(data)}`);
                    for(let i = 0; i < data.length; i++)
                    {
                        options = document.createElement('option');
                        options.value = data[i].name;
                        options.label = data[i].name;
                      // setOptions(data[i].name);
                      dropdown.add(options);
                        console.log(`OPTION: ${options}`);

                    }
                })
            }
        )

        
    }
useEffect(() => {
        
        fetchStates();
},[]);
          
return (
        <div className='attribute-edit-container'>
            <div className='attribute-name'>{'State'}</div>
            <Select id="select">
            </Select>
       );
} //StateSelect

Please help. Thank you

2
  • Does this answer your question? How do I create a dynamic drop down list with react-bootstrap Commented Jul 30, 2020 at 17:13
  • You are manipulating the DOM, but that's not how React works. You need const [states, setStates] = useState([]) and use list rendering to turn states into a bunch of options in your JSX. Then call setState() and pass the array of states after your fetch has loaded them. A key concept of React is following the "separation of content and presentation" paradigm. Commented Jul 30, 2020 at 17:15

2 Answers 2

1

I dont understand why if you use react to build your fontend you use document.createElement to manipulate the DOM.

With react you can render the components according to the state, try to chain the promises in the correct way, my correction to your code is this:

function StateSelect({ values, initial }) {
  const [dataFetch, setDataFetch] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  async function fetchStates() {
    setIsLoading(true);
    fetch('url')
      .then(response => {
        if (response.status !== 200) {
          console.warn('State Object Not Fetched' + response.status);
          return new Error(response.status);
        }
        return response.json();
      })
      .then(data => {
        console.log(`STATES: ${JSON.stringify(data)}`);
        setDataFetch(data);
        setIsLoading(false);
      })
      .catch(err => {
        setIsLoading(false);
        setError(err);
      });
  }

  useEffect(() => {
    fetchStates();
  }, []);

  return isLoading ? (
    <div>Loading</div>
  ) : error ? (
    <div>error</div>
  ) : (
    <div className='attribute-edit-container'>
      <div className='attribute-name'>{'State'}</div>
      <Select id='select'>
        {dataFetch.length > 0 &&
          dataFetch.map(item => (
            <option key={item._id} value={item.name}>
              {item.name}
            </option>
          ))}
      </Select>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your response. But dataFetch is always empty.. I added console.log to verfiy and it always returns an empty array. As a result I am always getting an empty drop down.
Always will be empty, you need to use fetch with a correct parameter, in your first code you use .then without fetch, you need to use fetch correctly
I would appreciate if you could help me understand this. Please can you elaborate or show an example of what you meant. My understanding is in the second '.then' when we call setDataFetch(data) that would set dataFetch's value. I verified there is data in 'data'. And as I mentioned in the original post the fetch() is working. I am receiving a valid JSON object.
Yes, I can help you, look, in your first code in the line 6 after you write dropdown.length = 0 you use .thenit is a mistake, because you dont call any fetch data. To help you, i need understand where you want yo fetch data to build the options, and you need to learn how use fetch function if you want yo call a api to build your options
Ahh, my bad. I accidentally missed the fetch statement when copying, pasting code here. But in the altered/updated code that you have provided, can you help me understand that because dataFetch comes out empty and so does the <Select> component
0

You are not supposed to manipulate the DOM with react. Just create your drop down menu and then map through the objects and return that value

{states.map((state) => {
    return <MenuItem value={state._id}>{state.name} 
</MenuItem>;
})}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.