1

I have a function that runs a validation and sets a state variable based off of the results of the check. I need to pass the variable to upload via API call.

My issues is that the state variable is not updating and is passing in the initial state ( null ) when I need to pass the updated serviceSelected variable in the api call.

How would I go about solving this?

current code

const [serviceSelected, setServiceSelected] = useState(null)

function checkServicesSelected () {

       if (photography === true && video === false && drone === false){
            setServiceSelected(PhotographyService);
        } else if(photography === true && video === true && drone === false){
            setServiceSelected(PhotographyVideoService);
        } else if (photography === true && video === true && drone === true){
            setServiceSelected(allThreeServices);
        } else if (photography === false && video === true && drone === false){
            setServiceSelected(VideoService);
        } else if (photography === false && video === true && drone === true){
            setServiceSelected(VideoDroneService);
        } else if (photography === true && video === false && drone === true){
            setServiceSelected(PhotographyDroneService);
        } else if (photography === false && video === false && drone === true){
            setServiceSelected(DroneService);
        }
    }


/// first runs the check, then makes an api call. 

 async function completeApplication() {

    setShowSubmitForm(true);        

    try {
        /// run check
        await checkServicesSelected()

        /// pass info to uploadInfo Function 
        const UploadProspectInfo = await UploadInfo({service: serviceSelected})

     } catch (e) {
       alert(e.message);

          }

       setShowThankYou(true); 
   }

Updated Code Now Working

 useEffect(() => {
    if(serviceSelected){
        UploadInfo({service: serviceSelected})
        .catch(function (e) {
            alert(e.message);
        });
        setShowThankYou(true)
    }
}, [serviceSelected]);


function completeApplication() {
        setShowSubmitForm(true);
        checkServicesSelected();  
    }

Jordan Spackman
  • 333
  • 1
  • 6
  • 23

2 Answers2

2

You can use useEffect hook to achieve it

...
...
React.useEffect(() => {
(async function() {
  try {
         /// pass info to uploadInfo Function 
         const UploadProspectInfo = serviceSelected && await UploadInfo({service: serviceSelected})
         //serviceSelected && setShowThankYou(true); // you need it here?

    }catch (e) {
       alert(e.message);
     }
})();

  }, [serviceSelected]);


/// first runs the check, then makes an api call. 

function completeApplication() {

        setShowSubmitForm(true);        

        /// run check
        checkServicesSelected()

        //setShowThankYou(true); // maybe you don't need it here?
   }

side note:

01) self-invoking function

02) async in useEffect

blueseal
  • 2,726
  • 6
  • 26
  • 41
1

setServiceSelected re-renders the component so on this line there will be old serviceSelected value:

const UploadProspectInfo = await UploadInfo({service: serviceSelected})

So you have two options if you want to store serviceSelected value in state (for other purposes than make the api call) you have to use useEffect like this:

 useEffect(() => {
    if(serviceSelected){
        UploadInfo({ service: serviceSelected })
        .catch(function (e) {
            alert(e.message);
        });
    }
}, [serviceSelected]);


/// first runs the check, then makes an api call. 

function completeApplication() {
    setShowSubmitForm(true);
    checkServicesSelected();
    setShowThankYou(true);
}

but if you don't want to store in state you can make checkServicesSelected function pure and return the selected service instead of storing in state.