- 背景**
- 该项目的想法是有一个不同应用程序的下拉菜单(材料UI中的 accordion )。
- 为每个应用程序提供与之相关的API调用。
- 为每个API提供传入和传出参数。
我成功地拥有了我的应用程序列表,并在每一个API下面涉及他们,但我阻止恢复每个API的参数。
显示内容如下所示:
申请编号1
─ ─空气污染指数1
- -参数
由于我还在学习React的一般知识,我在"API"检索方面遇到了麻烦。
- 以下是我的代码:**
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>
)
}
您可以看到,我试图为参数重现与API相同的方法。
我可以看到我的常量"ListeParametre"没有被调用,而是被调用了Object.values(API)(我知道API是一个对象,必须将其转换为Array才能应用forEach
APIs.length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));
但是现在没有发送任何参数,Axios调用时会出现错误(console.log('ID : ' + IdAPI)
未定义)
注意:API.length似乎未定义
- 编辑1:**通过console. log(对象条目(API))进入API内部
API : [["1", [{"api_id": IdValue, "api_uri": UriValue, "api_description": DescriptionValue, ...}, {...}]]]
- EDIT 2:**在API上使用Object. entries时,它似乎会进入第一个应用程序的API的第一行。但随后会出现404错误,因为api_id未定义。
useEffect(() => {
Object.entries(APIs).length && Object.entries(APIs).forEach((api) => ListeParametre(api.api_id))
}, [APIs])
有人能解释一下我的错误吗?谢谢你的帮助!如果我的问题/标题不清楚,请告诉我,我可以编辑它。
4条答案
按热度按时间7fyelxc51#
为什么要在对象上调用
.length
因为您已将Object设置为空状态
const [APIs, setAPIs] = useState({});
并且您正在对象上调用
.length
函数,因为它仅用于数组我想这就是为什么它从来不为真它每次都返回未定义
你可以这样使用:
Object.entries(API).length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));
v6ylcynt2#
对不起,这种代码的和平对我来说没有意义,也许你可以在API调用中提供带有存根的沙箱示例?
在这里,您检查applis是否为空字符串,但默认情况下将其设置为array,因此除非将applis设置为string,否则此语句将始终为false,并且您设置applic的唯一位置是loadRessources函数
然后在“else”语句中检查applis是否具有长度,但它将始终为空数组,因为在该if语句中调用了设置applis(loadRessources)的函数,而该函数永远不会执行
r9f1avp53#
我认为这里是错误的:
在
loadRessources
中,你调用setApplis
,你想调用loadRessources
,if (applis == "" )
,但是你设置状态的方式是这样的。所以if语句应该是
您正在设置
ListeAPI
内部的API,该API在以下情况下调用:由于您从未调用过
loadRessources
,因此不会设置applis
,也不会调用ListeAPI
。由于未调用setAPIs
,因此不会设置setAPIs
,因为您是在ListeAPI
内部设置它。由于未设置API,因此
APIs.length
是错误的。fbcarpbf4#
在您的EDIT1:我看到对象是多个数组。
我觉得你可以试试这个