getResource() in a nested for loop and props not updated with fetched data
Hi
Please I have this issue when fetching Layout Builder, I have the following code.
export default function LB(props){
const LB: Array<any> = props.LBPage.layout_builder__layout;
/*const pageStructure = {
sectionsNum: LB.length,
sectionsSetting: [],
contentTypes: [],
};
// Add each section setting to the pageStructure
LB.forEach(section => {
const sectionSetting = {
columns: null,
column_widths: section.section.layout_settings.column_widths,
context_mapping: section.section.layout_settings.context_mapping,
label: section.section.layout_settings.label,
};
sectionSetting.columns = sectionSetting.column_widths ? sectionSetting.column_widths.split('-').length : null;
pageStructure.sectionsSetting.push(sectionSetting);
});*/
console.log(LB, props.resource, props.resource[1], props);
return (
<Fragment>
{
LB.map(section => {
console.log(props.resource);
return <section className={
section.section.layout_settings.column_widths
?
section.section.layout_settings.column_widths.split('-').length + '-col' + ' ' + 'col-' +section.section.layout_settings.column_widths
:
'1-col'
}
>
</section>;
})
}
</Fragment>
);
}
export async function getStaticProps(){
let resource = [];
let resources = [];
const LBPage = await getResource('node--page', '6acb560b-f999-4011-9bab-160856d21f9f')
LBPage.layout_builder__layout.forEach((section, i) => {
resource.push({section: []});
//console.log('sections: ', section.section.components)
// console.log('section.section.components: ', section.section.components, section.section);
section.section.components.forEach(async (comp, j) => {
//console.log('resource[i]: ', i, j);
//console.log('component: ', comp.provider);
//console.log('params: ', comp.configuration.provider + "--basic", comp.configuration.id, comp.configuration.id.replace(comp.configuration.provider + ':', ''));
if(comp.configuration.provider === 'block_content'){
const nodeType = comp.configuration.provider + "--basic";
const nodeUid = comp.configuration.id.replace(comp.configuration.provider + ':', '');
resources.push('response');
const blocks = await getResource(nodeType, nodeUid);
console.log(i, 'Response: ', resource[i].section, blocks);
//resource[i].section.push(blocks);
setTimeout(() => {
resource[i].section.push(blocks);
}, 15000);
resource[i].section.push('blocks');
resources.push(blocks);
}
});
});
return {
props: {
LBPage,
resource,
resources,
},
};
}
LBPage fetched normally but resource has empty arrays here is it hen logged on the devtool
resource: [
{
"section": []
},
{
"section": []
},
{
"section": []
},
{
"section": []
}
]
every section there should has it's own blocks inside the array, by the way, the blocks fetched has been logged on the server nodejs but not passed to props
resources is just to know whether the block inside the if condition work or not
Thanks in advance.
Hello, each interation call in:
section.section.components.forEach(async (comp, j) => {...}
returns a Promise that is not resolved, try to wrap this loop with "await Promise.all(...)".
Hello, each interation call in:
section.section.components.forEach(async (comp, j) => {...}returns a Promise that is not resolved, try to wrap this loop with "await Promise.all(...)".
Hi
Thanks for your reply
I did what you say but it doesn't work, it's really weird

"async" returned from forEach returns an unresolved Promise, that receives data back after execution getStaticProps function body.
await Promise.all(section.section.components.forEach(async (comp, j) => {...});
Anyway do you need to call
const blocks = await getResource(nodeType, nodeUid);
inside loop? This is not a good practise, because you spin every request for each iteration. Can't you get those data before loop, and avoid await/async within loop?
@ansdb which module are you using for layout builder and JSON:API?
You're probably using the layout builder patch.
@soft4net is right. You should wrap the top forEach in a Promise.all.
await Promise.all(LBPage.layout_builder__layout.forEach())
You could also use a for ... of ...
const page = await getResource('node--page', '6acb560b-f999-4011-9bab-160856d21f9f')
for (const section of page.layout_builder__layout) {
for (const component of section.components) {
// .....
// Do your getResource call here.
const blocks = await getResource(nodeType, nodeUid);
// ....
}
}
Hi
@shadcn Yes I use that layout builder patch
Okay thanks a lot, I will test what you say and come back to you with the result
Thanks a lot for both of you.
Hi @shadcn
Thanks a lot I've got the block using for loop .
I've tried Promise.all it has to work but maybe I did a mistake, anyway.
Please I have a question why I'm not able to push blocks fetched using the first approach with .forEach method and i can push using the for loop?
Thanks a lot.