Search code examples
javascriptnode.jsreactjsasynchronousreact-admin

How can I use an asynchronous javascript function like fetch inside a FormDataConsumer


I need to use a fetch inside the FormDataConsumer tag but it seems FormDataConsumer does not support async functions. This code didn't work for me:

<FormDataConsumer>
{
    async ({ formData, scopedFormData, getSource, ...rest }) => {
        return await fetch('/api/v1/attributes/'+scopedFormData.single_attributes_label)
        .then(res => res.json())
        .then(data => {
            console.log(JSON.stringify(data));
            //return JSON.stringify(data);
            resolve(JSON.stringify(data));
        });
        return JSON.stringify(scopedFormData);
    }
}
</FormDataConsumer>

I also checked this code and this one also didn't work:

async function getAttrItem(id) {
  return await fetch(`/api/v1/attributes/${id}`).then(response => response.json())
}

...

<FormDataConsumer>
{
    async ({ formData, scopedFormData, getSource, ...rest }) => {
        return await JSON.stringify(getAttrItem(scopedFormData.single_attributes_label));
    }
}
</FormDataConsumer>

But when I use this one, it works in the console:

<FormDataConsumer>
{
    ({ formData, scopedFormData, getSource, ...rest }) => {
        fetch('/api/v1/attributes/'+scopedFormData.single_attributes_label)
        .then(res => res.json())
        .then(data => {
            console.log(JSON.stringify(data));
            //return JSON.stringify(data);
            resolve(JSON.stringify(data));
        });
        return JSON.stringify(scopedFormData);
    }
}
</FormDataConsumer>

Should I use this FormDataConsumer for filling an object and then inside the other FormDataConsumer check the object?


Solution

  • My issue was fixed with this code:

    <FormDataConsumer>
        {
            ({ formData, scopedFormData, getSource, ...rest }) => {
                return scopedFormData && formData && "type" in formData && <ReferenceInput label="Attribute Label" source={getSource('single_attributes_label')} reference={`attributes`} filter={{ document_type: formData.type }}>
                <AutocompleteInput optionText="title" optionValue="id" />
                </ReferenceInput>
            }
        }
    </FormDataConsumer>
    <FormDataConsumer>
        {
            ({ formData, scopedFormData, getSource, ...rest }) => {
                return "type" in formData && "single_attributes_label" in scopedFormData && <AttribValue source={getSource('single_attributes_value')} reference={`attributes`} filter={{ document_type: formData.type, id: scopedFormData.single_attributes_label, method: "getOptions" }} attribute={scopedFormData.single_attributes_label} {...rest} />
            }
        }
    </FormDataConsumer>
    
    const AttribValue = props => {
      const [data, setData] = useState();
      console.log('props', props);
      useEffect(() => {
        fetch("/api/v1/attributes/" + props.attribute)
          .then(res => res.json())
          .then(data => {
            setData({ data });
          });
      }, [props.attribute, props.label]);
    
      if (!data) {
        return 'Please Wait...';
      }
      let newProp = Object.assign({}, props, { label: "Attributes Value" });
      return data.data.attribute_type == 'multiselect' ? <ReferenceArrayInput {...newProp}><AutocompleteArrayInput optionText="text" optionValue="id" /></ReferenceArrayInput> : <ReferenceInput {...newProp}><AutocompleteInput optionText="text" optionValue="id" /></ReferenceInput>;
    };