Home App Docs Blog Github

Dynamic default children with API

Hi, how can I build dynamic default children for a component in a builder.js file?
I need to send an API and based on the response create default children but this should not happen at the component level but builder.js file.

Hi @mossen, thanks for reaching out! Can you provide a few more details?

  • What framework are you using?
  • What Builder libraries are you using?
  • Can you provide a code sample?

Thanks!

Hi Kara,

I am using Gatsby, following is what I am trying to achieve:

const getFormFields = async () => {
  let data;

  await api({
    method: 'GET',
    url: `${process.env.GATSBY_CONNECT_API}`,
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    }
  })
    .then(result => {
      data = result?.data?.ClaimQuestionSettings?.QuestionDefinitions;
    })
    .catch(error => {
      console.log('error :>> ', error);
    });

  return data;
};

export const defaultChildren = [
 // Sending API
  ...getFormFields().map(field => {
        const options = {
          options: field?.options || null,
          name: field.Name,
          type: field.type || 'text',
          placeholder: field.DisplayText,
          label: field.DisplayText
          // required: field.IsAnswerRequired,
        };
        if (field.component === 'File input') {
          options.labelPlacement = 'top';
        }

    return {
      '@type': '@builder.io/sdk:Element',
      responsiveStyles: {
        large: {
          marginTop: '10px',
          marginBottom: '10px'
        }
      },
      component: {
        name: field.component,
        options,
        noWrap: true
      }
    };
  }),
];

// using defaultChildren
Builder.registerComponent(Form, {
name: 'Standard Single Claim Form',
image: form,
noWrap: false,
canHaveChildren: true,
defaultChildren
});

Hey @mossen , you want to organize your code in a way that all needed async operation is done before the registerComponent call, something like this:

export async function registerForm() {
  const data = await getFormData();
  const defaultChildren = getDefautlChildren(data);
  Builder.registerComponent( ....);
}
1 Like

@aziz Thanks for the suggestion, I’ve got this working however the request gets sent out on all the pages view even when that component is not used in the page. Do you have any solution for this? for now I am using Builder.isEditing for stopping it.

const getDefaultChildren = async () => {
  // prevent sending request on the view pages
  if (!Builder.isEditing) {
    return null;
  }
 // await Fetch data by API
}
Builder.registerComponent(Form, {
  name: 'Standard Single Claim Form',
  defaultChildren: 'getDefaultChildren()',
}

Another question that I have is how can I access state here or get an input from editor? I have an input that should be field in the editor and that value needs to be used as a query parameter for this API call.
maybe something like following?

Builder.registerComponent(Form, {
      name: 'Standard Single Claim Form',
      defaultChildren: 'options => getDefaultChildren(options.get("ID"))', // get the input value here
    }

Hey @mossen! One of our software engineers reached out to you directly to set up some time to chat :slight_smile: