Context
- The idea of the project is to have a drop-down menu (an Accordion in Material-UI) of the different Applications.
- To have for each Application its API calls concerning it.
- To have for each API its incoming and outgoing parameters.
I succeeded in having my list of applications and below each one the APIs concerning them but I block to recover for each API their parameters.
The display looks something like this:
Application n°1
-- APIs 1
-- -- Parameters
Being still learning React in general, I had trouble with the "API" retrieval.
Here is my code:
export default function documentationv2() {
// Getteur - Setteur
const [applis, setApplis] = useState([]);
const [APIs, setAPIs] = useState({});
const [parametres, setParametres] = useState({});
// Chargement
const loadRessources = () => {
axios.get('/api/documentation/application')
.then((response) => {
setApplis(response.data);
})
.catch((error) => console.log(error));
}
// Liste des APIs pour une application
const ListeAPI = (AppliID) => {
axios.get('/api/documentation/api?app_id=' + AppliID)
.then((response) => {
setAPIs(prev => {
return {
...prev,
[AppliID]: response.data
}
})
})
}
// Liste des paramètres pour une API
const ListeParametre = (IdAPI) => {
console.log('ID : ' + IdAPI)
axios.get('/api/documentation/parametre?api_id=' + IdAPI)
.then((response) => {
setParametres(prev => {
return {
...prev,
[IdAPI]: response.data
}
})
})
}
useEffect(() => {
if (applis == "" ) {
loadRessources();
}
else{
console.log('Length Appli : ' + applis.length)
console.log('Appli : ' + applis.toString())
applis.length && applis.forEach((application) => ListeAPI(application.IDAPPLI));
}
}, [applis])
useEffect(() => {
console.log('Length API : ' + APIs.length)
console.log('API : ' + APIs)
// APIs.length &&
APIs.length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));
}, [APIs])
return (
<Grid container className={classes.root}>
{/* -- BODY -- */}
<Grid item className={classes.Body}>
<Grid container className={classes.GridContainerBody}>
{applis.map((application, index) => (
<div className={classes.DivContainerBody}>
<Grid item className={classes.GridItemLeftBody}>
<Accordion key={application.IDAPPLI} className={classes.AccordionBody}>
<AccordionSummary expandIcon={<IconButton className={classes.ButtonBodyShow} disableRipple={true}><ExpandMoreIcon/></IconButton>}>
<Typography>
{application.NOMAPPLI} - ({application.NBAPI})
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.AccordionDetailsApplication}>
{APIs[application.IDAPPLI] && APIs[application.IDAPPLI].map((api, index) => (
<div className={classes.DivDetailsApplication}>
<Accordion key={api.api_id} className={classes.AccordionBody}>
<AccordionSummary expandIcon={<IconButton className={classes.ButtonBodyShow} disableRipple={true}><ExpandMoreIcon/></IconButton>}>
<div className={classes.AccordionSumAPI}>
<Typography>
{api.api_uri}
</Typography>
<Typography>
{api.api_description}
</Typography>
<div className={classes.AccordionSumAPIDiv}>
<Chip
style={{backgroundColor: "#06d6a0", width: "fit-content"}}
label={api.api_version}
/>
<Chip
style={{backgroundColor: "#ffd166", width: "fit-content"}}
label={api.api_response_type}
/>
</div>
<div>
<Typography>
Créé par {api.api_creation_user} le {api.api_date_creation}.
</Typography>
<Typography>
Modifié par {api.api_maj_user} le {api.api_date_maj}.
</Typography>
</div>
</div>
</AccordionSummary>
<AccordionDetails className={classes.GridContainerBody}>
{parametres[api.api_id] && parametres[api.api_id].map((parametre, index) => (
<div key={index}>
<Typography>
Paramètre(s) d'entrée :
</Typography>
<Divider className={classes.ParamDivider}/>
<Chip
style={{backgroundColor: "#06d6a0", width: "fit-content"}}
label={parametre.INPUT}
/>
<Typography style={{marginTop: "1%"}}>
Paramètre(s) de sortie :
</Typography>
<Divider className={classes.ParamDivider}/>
<Chip
style={{backgroundColor: "#ffd166", width: "fit-content"}}
label={parametre.OUTPUT}
/>
</div>
))}
</AccordionDetails>
</Accordion>
</div>
))}
</AccordionDetails>
</Accordion>
</Grid>
<Grid item className={classes.GridItemRightbody}>
<div>
<Tooltip title="Mot de passe" placement="top" arrow>
<IconButton
className={classes.ButtonHeader}
disableRipple={true}
>
<LockIcon/>
</IconButton>
</Tooltip>
</div>
<div>
<Tooltip title="Télécharger doc
" placement="top" arrow>
<IconButton
className={classes.ButtonHeader}
disableRipple={true}
>
<GetAppIcon/>
</IconButton>
</Tooltip>
</div>
</Grid>
</div>
))}
</Grid>
</Grid>
</Grid>
)
}
You can see that I tried to reproduce the same method for the parameters as on the APIs.
I could see that my const "ListeParametre" was not called, with Object.values(APIs) it is called (I understood that API is an object and that I had to convert it to an Array to be able to apply a forEach
APIs.length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));
But now no parameters are sent, giving an error with the Axios call
(console.log('ID : ' + IdAPI) is undefined)
Note: API.length seems to be undefined
EDIT 1 : Inside API via console.log(Oject.entries(APIs))
API : [["1", [{"api_id": IdValue, "api_uri": UriValue, "api_description": DescriptionValue, ...}, {...}]]]
EDIT 2 : When using the Object.entries on API it seems to go the first row of APIs for the first application. But then a 404 error comes in because api_id is undefined.
useEffect(() => {
Object.entries(APIs).length && Object.entries(APIs).forEach((api) => ListeParametre(api.api_id))
}, [APIs])
Can someone explain my error? Thanks for any help! If my problem/title is not clear, tell me please so I can edit it.