Populate input fields from axios response reactjs

Viewed 965

I have simple fields. I want to populate the input boxes based on the data that I get from axios response. See below image

enter image description here

I am using hooks, to save data to state. My question is how I am able to populate input boxes upon clicking get details button (response from api).

see below codes

const [data, setData] = useState([])
const [advisoryDetails, setadvisoryDetails] = useState({
    ADVISORYID: '',
    ADVISORYDESC: '',
    CREATEDBY:'',
    MODIFIEDBY:'',
    STATUS1: ''        
})
const [advisoryDetails1, setadvisoryDetails1] = useState([])
const [advisoryID, setadvisoryID] = useState('')

const getAdvisoryTest = async () => {
    await axios.post('/API',advisoryID)
    .then(response => {
        console.log(response.data)
        setData(response.data)
        console.log('data',data)
        setadvisoryDetails1(response.data)
        console.log('advisoryDetails1',advisoryDetails1)
        alert('success')
    })

advisoryDetails1.map(adv => {
        advisoryDetails.ADVISORYID = adv.ADVISORYID;
        advisoryDetails.ADVISORYDESC = adv.ADVISORYDESC;
        advisoryDetails.CREATEDBY = adv.CREATEDBY;
        advisoryDetails.MODIFIEDBY = adv.MODIFIEDBY;
        if(adv.CREATEDBY && adv.MODIFIEDBY != '')
        {
            advisoryDetails.STATUS1 = 'Modified'
        }
        else{ advisoryDetails.STATUS1 = 'New'}

        console.log('populate',advisoryDetails)
    })
}
const txtAdvIdOnChange = e =>{
    setadvisoryID(prevState =>({
        ...prevState,
        'ADVISORYID':e.target.value
    }));
    console.log('onChange ID:',advisoryID)
}
return(
    <div>
        <label>AdvisoryID: </label>
        <input type='text' placeholder='Advisory ID' className='txtAdvisoryID' onChange={txtAdvIdOnChange} />
<button onClick={()=>getAdvisoryTest()}>Get Details</button>
        <br /><br />
<label>Advisory Desc: </label>
        <input type='text' placeholder='textbox1' className='txtAdvisoryDesc' value={advisoryDetails&&advisoryDetails.ADVISORYDESC} disabled/>
        <br/>
        <label>New / Modified: </label>
        <input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails&&advisoryDetails.STATUS1} disabled/>
</div>)

On those codes input boxes was not populated, even in console.log Hope you can help me thank you.

3 Answers

when you click the get details button your state was not updating that was the issue(value only change when the state was updated otherwise it is not updated)

//before don't do like this 
advisoryDetails1.map(adv => {
        advisoryDetails.ADVISORYID = adv.ADVISORYID;
        advisoryDetails.ADVISORYDESC = adv.ADVISORYDESC;
        advisoryDetails.CREATEDBY = adv.CREATEDBY;
        advisoryDetails.MODIFIEDBY = adv.MODIFIEDBY;
        if(adv.CREATEDBY && adv.MODIFIEDBY != '')
        {
            advisoryDetails.STATUS1 = 'Modified'
        }
        else{ advisoryDetails.STATUS1 = 'New'}

        console.log('populate',advisoryDetails)
    })





//after(only last element of advisoryDetails1 array was updated in the state)
 advisoryDetails1.forEach(adv => {
    let STATUS1 ='New'
    if(adv.CREATEDBY && adv.MODIFIEDBY != '')
    {
        STATUS1  = 'Modified'
    }
   
     setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
        ADVISORYDESC:adv.ADVISORYDESC,
        CREATEDBY:adv.CREATEDBY,
        MODIFIEDBY:adv.MODIFIEDBY,
       STATUS1:STATUS1 
     })
   })

if you want to view your last element in your advisoryDetails1 array do like this

 let adv=advisoryDetails1[advisoryDetails1.length -1];
    let STATUS1 ='New'
    if(adv.CREATEDBY && adv.MODIFIEDBY != '')
    {
        STATUS1  = 'Modified'
    }
   
     setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
        ADVISORYDESC:adv.ADVISORYDESC,
        CREATEDBY:adv.CREATEDBY,
        MODIFIEDBY:adv.MODIFIEDBY,
        STATUS1:STATUS1 
     })
 


 //it update your advisoryDetails state when advisoryDetails1 changed
  useEffect(()=>{
    advisoryDetails1.forEach(adv => {
    let STATUS1 ='New'
    if(adv.CREATEDBY && adv.MODIFIEDBY != '')
    {
        STATUS1  = 'Modified'
    }
   
     setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
        ADVISORYDESC:adv.ADVISORYDESC,
        CREATEDBY:adv.CREATEDBY,
        MODIFIEDBY:adv.MODIFIEDBY,
       STATUS1:STATUS1 
     })
   })
  },[advisoryDetails1]);
//check whether advisoryDetails is changed or not 
      useEffect(()=>{
        console.log('populate',advisoryDetails)
      },[advisoryDetails])

everything fine but doesn't do like this only the last element of the array was updated so you must need some changes based on your requirements

I think you can refactor your code like below. I've moved set setadvisoryDetails to within .then() of axios because you're using the same data and you're don't have to go through the loop if you just want the last iteration's value. And in the inputs you don't have to check if advisoryDetails exists or has non empty value because you've initialized it in const [advisoryDetails, setadvisoryDetails] = useState({...})

const App = (props) => {
  const [data, setData] = useState([])
  const [advisoryDetails, setadvisoryDetails] = useState({
    ADVISORYID: '',
    ADVISORYDESC: '',
    CREATEDBY: '',
    MODIFIEDBY: '',
    STATUS1: ''
  })
  const [advisoryDetails1, setadvisoryDetails1] = useState([])
  const [advisoryID, setadvisoryID] = useState('')

  const getAdvisoryTest = () => {
    axios.post('/API', advisoryID)
      .then(response => {
        const respData = response.data;
        setData(respData)
        setadvisoryDetails1(respData)

        console.log({
          respData, data, advisoryDetails1
        });

        alert('success');

        if (respData.length > 0) {
          const adv = respData[respData.length - 1];
          setadvisoryDetails((prevState) => ({
            ...prevState,
            ...adv,
            STATUS1: adv.CREATEDBY && adv.MODIFIEDBY != '' ? 'Modified' : 'New'
          }))
        }

      })
  }

  const txtAdvIdOnChange = e => {
    setadvisoryID(prevState => ({
      ...prevState,
      'ADVISORYID': e.target.value
    }));
    console.log('onChange ID:', advisoryID)
  }

  return (
    <div>
      <label>AdvisoryID: </label>
      <input type='text' placeholder='Advisory ID' className='txtAdvisoryID' onChange={txtAdvIdOnChange} />
      {/* If you're just passing a function without any param or event params, then just pass the function name like a variable */}
      <button onClick={getAdvisoryTest}>Get Details</button>
      <br /><br />
      <label>Advisory Desc: </label>
      <input type='text' placeholder='textbox1' className='txtAdvisoryDesc' value={advisoryDetails.ADVISORYDESC} disabled />
      <br />
      <label>New / Modified: </label>
      <input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails.STATUS1} disabled />
    </div>
  );
}

On your input value properties try adding a space either side of the &&.

<input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails.STATUS1 && advisoryDetails.STATUS1} disabled/>
Related