Nitin Bisht
Nitin Bisht

Reputation: 5361

Get data on dropdown based on another dropdown value

Sample API data - http://demo6007276.mockable.io/test

I have three dropdowns as followed:

  1. From Release
  2. To Release
  3. Compatability

Once I select specific from release then all to releases associated with that from release should be available in the To Release dropdown which is working. Now I am unable to select a specific to release from the To release dropdown and it should show its compatibility in the Compatability dropdown. Here is my code:

const URL = "http://demo6007276.mockable.io";

export const fetchRelease = async () => {
    try {
        const { data } = await axios.get(`${URL}/test`);
        return data;
    } catch (error) {
        console.log(error);
    }
}
function HomeFragement() {
    const classes = Styles();

    const [releases, setReleases] = React.useState([]);
    const [fromRelease, setFromRelease] = React.useState('Release1');

    const [toRelease, setToRelease] = React.useState('');
    const [compatability, setCompatability] = React.useState('');

    React.useEffect(() => {
        let unmounted = false;
        const handleFetchReleases = async () => {
            const response = await fetchRelease();
            if (!unmounted) {
                setReleases(response);
            }
        }
        handleFetchReleases();
        return () => {
            unmounted = true;
        };
    }, [])

    let tRelease = releases.filter(item => {
        return item.fromRelease === fromRelease
    })

    let compt = releases.filter(item => {
        return item.fromRelease === fromRelease
    })

    const handleChangeFromRelease = (e) => {
        setFromRelease(e.target.value);
    }

    const handleChangeToRelease = (e) => {
        setToRelease(e.target.value);
    }

    const handleChangeCompatability = (e) => {
        setCompatability(e.target.value);
    }

    return (
        <div>
            <Box bgcolor="#fff" boxShadow={1} p={2}>
                <form className={classes.root} autoComplete="off">
                    <Grid container spacing={3}>
                        <Grid item xs={3}>
                            <InputLabel>From Release</InputLabel>
                            <Select value={fromRelease} onChange={(e) => handleChangeFromRelease(e)}>
                                {
                                    releases.map((pvalue, i) => {
                                        return <MenuItem key={i} value={pvalue.fromRelease}> {pvalue.fromRelease} </MenuItem>
                                    })
                                }
                            </Select>
                        </Grid>

                        <Grid item xs={3}>
                            <InputLabel>To Release</InputLabel>
                            <Select value={toRelease} onChange={(e) => handleChangeToRelease(e)}>
                                {
                                    tRelease[0] && tRelease[0].releases.map((pvalue, i) => {
                                        return <MenuItem key={i} value={pvalue.toRelease}> {pvalue.toRelease} </MenuItem>
                                    })
                                }
                            </Select>
                        </Grid>

                        <Grid item xs={3}>
                            <InputLabel>Compatability</InputLabel>
                            <Select value={compatability} onChange={(e) => handleChangeCompatability(e)}>
                                {
                                    compt[0] && compt[0].releases.map((pvalue, i) => {
                                        return <MenuItem key={i} value={pvalue.compatability}> {pvalue.compatability} </MenuItem>
                                    })
                                }
                            </Select>
                        </Grid>                     
                    </Grid>
                </form>
            </Box>
        </div>
    )
}
export default HomeFragement

Any suggestion, please?

Upvotes: 1

Views: 100

Answers (1)

Prathamesh Koshti
Prathamesh Koshti

Reputation: 1360

I made few changes in your code. I created new state for compatibilities array which will hold compatibilities based on the selected toRelease (Even though right now you are getting only one compatibility, in future you may receive many, so better to have an array).

const [compatibilities, setCompatabilities] = React.useState([]);

Then modified below method:

const handleChangeToRelease = (e) => {
    const value = e.target.value;
    setToRelease(value);
    // first get the selected fromRelease
    const fromReleaseObj = releases.find(release => release.fromRelease === fromRelease);
    // by using fromRelease object get the selected toRelease object
    const toReleaseObj = fromReleaseObj.releases.find(release => release.toRelease === value);
    // now set the array we defined earlier using react hook to `toReleaseObj`'s compatibility
    setCompatibilities([toReleaseObj.compatability])
};

In your render method, make sure you are using the compatibilities array which was defined earlier in this answer.

<Grid item xs={3}>
  <InputLabel>Compatability</InputLabel>
    <Select
      value={compatability}
      onChange={(e) => handleChangeCompatability(e)}
    >
      {compatibilities.map((compatability, i) => {
        return (
        <MenuItem key={i} value={compatability}>
          {" "}
          {compatability}{" "}
        </MenuItem>
      );
    })}
  </Select>
</Grid>

Here's the code sandbox link: https://codesandbox.io/s/happy-bird-bme2u, It won't work because you might get some CORS error and in console you may see Failed to fetch. So make sure you export it using file menu and download it in your system.

Once downloaded, using terminal install npm packages using the command npm run install and run it using npm start.

Upvotes: 1

Related Questions