I'm building an electron app and using react for the UI. I have this page in which I fill a form to create an invoice from a pre-defined template. I this error on the first render and after I refresh it goes away. Note that if I keep refreshing at some point it appears again.
Here is the Error:
```
at PdfViewerBase.updateLeftPosition (webpack-internal:///./node_modules/@syncfusion/ej2-pdfviewer/src/pdfviewer/base/pdfviewer-base.js:6265:42)
at PdfViewerBase.renderPageContainer (webpack-internal:///./node_modules/@syncfusion/ej2-pdfviewer/src/pdfviewer/base/pdfviewer-base.js:6132:39)
at PdfViewerBase.initPageDiv (webpack-internal:///./node_modules/@syncfusion/ej2-pdfviewer/src/pdfviewer/base/pdfviewer-base.js:5327:22)
at PdfViewerBase.pageRender (webpack-internal:///./node_modules/@syncfusion/ej2-pdfviewer/src/pdfviewer/base/pdfviewer-base.js:2976:14)
at PdfViewerBase.requestSuccess (webpack-internal:///./node_modules/@syncfusion/ej2-pdfviewer/src/pdfviewer/base/pdfviewer-base.js:2890:18)
at eval (webpack-internal:///./node_modules/@syncfusion/ej2-pdfviewer/src/pdfviewer/base/pdfviewer-base.js:2702:39)
```
And here is my Code:
```tsx
import { useCallback, useEffect, useMemo, useState } from 'react';
import {
Button,
Divider,
Flex,
Form,
Image,
Input,
InputNumber,
Radio,
Select,
Space,
Typography,
} from 'antd';
import type { FormProps, DatePickerProps } from 'antd';
import { useTranslation } from 'react-i18next';
import { createUseStyles } from 'react-jss';
import classNames from 'classnames';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation,
Print,
TextSelection,
TextSearch,
Inject,
} from '@syncfusion/ej2-react-pdfviewer';
import { useAppContext } from '../hooks/useAppContext';
import { MeasureUnit, PdfPageFormat } from '../../common/enums';
import { arrayBufferToBase64 } from '../utils/arraybuffer-to-base64';
import { InputTable } from '../components/InputTable';
import { InvoiceInputField } from '../components/InvoiceInputField';
type FormValues = {
fields: {
[key: string]: string | number | DatePickerProps['value'];
};
items: {
[key: string]: string | number | DatePickerProps['value'];
}[];
pageSettings: {
format: PdfPageFormat;
margin: {
top: number;
right: number;
bottom: number;
left: number;
};
marginUnit: MeasureUnit;
landscape: boolean;
};
};
const useStyles = createUseStyles({
templateImage: {
aspectRatio: '1 / 1.414',
border: '1px solid #dadce0',
borderRadius: 4,
'&:hover': {
cursor: 'pointer',
border: '1px solid var(--ant-layout-sider-bg)',
},
},
templateImageSelected: {
border: '1px solid var(--ant-layout-sider-bg)',
},
});
export function CreateInvoiceView() {
const {
invoiceTemplates,
appSettings: { locale },
logos,
} = useAppContext();
const [form] = Form.useForm();
const { t } = useTranslation();
const classes = useStyles();
const [template, setSelectedTemplate] = useState<InvoiceTemplate>(
invoiceTemplates[0],
);
const [pdfDataUrl, setPdfDataUrl] = useState<string | null>(null);
const mapFormValuesToDto = useCallback(
(values: FormValues) => {
if (values.fields.date) {
values.fields.date = (
values.fields.date as DatePickerProps['value']
).format('YYYY-MM-DD');
}
const dto: GenInvoiceOptions = {
template: template.name,
pageSettings: {
format: values.pageSettings.format,
margin: {
top:
values.pageSettings.margin.top + values.pageSettings.marginUnit,
bottom:
values.pageSettings.margin.bottom +
values.pageSettings.marginUnit,
left:
values.pageSettings.margin.left + values.pageSettings.marginUnit,
right:
values.pageSettings.margin.right + values.pageSettings.marginUnit,
},
landscape: false,
},
data: {
...values.fields,
items: values.items,
},
};
return dto;
},
[template],
);
const onFinish: FormProps<FormValues>['onFinish'] = useCallback(
(values) => {
const dto = mapFormValuesToDto(values);
console.log('dto', dto);
},
[mapFormValuesToDto],
);
const previewPdf = useCallback(async () => {
const values = form.getFieldsValue() as FormValues;
const dto = mapFormValuesToDto(values);
const pdfBuffer = await window.electron.previewPdf(dto);
const base64 = arrayBufferToBase64(pdfBuffer);
setPdfDataUrl(`data:application/pdf;base64, ${base64}`);
}, []);
useEffect(() => {
document.title = t('views:CreateInvoice.document.title');
previewPdf();
}, [t]);
const marginSuffixSelector = useMemo(
() => (
<Form.Item name={['pageSettings', 'marginUnit']} noStyle>
<Select
options={Object.values(MeasureUnit).map((v) => ({
label: v,
value: v,
}))}
/>
</Form.Item>
),
[],
);
return (
<Form
form={form}
layout='vertical'
initialValues={{
fields: { logo: template.defaultLogo },
items: [],
pageSettings: {
format: template.defaultFormat,
margin: {
top: 1,
bottom: 1,
left: 1,
right: 1,
},
marginUnit: MeasureUnit.Inches,
},
}}
onFinish={onFinish}>
<Form.Item>
<Typography.Title level={2} style={{ textDecoration: 'underline' }}>
{t('views:CreateInvoice.section.generalInformation')}
</Typography.Title>
</Form.Item>
<Form.Item>
<Flex style={{ overflowX: 'auto' }} justify='start' align='center'>
{invoiceTemplates.map((temp) => (
<Space
key={temp.name}
direction='vertical'
size={8}
style={{ maxWidth: 140 }}>
<Image
className={classNames({
[classes.templateImage]: true,
[classes.templateImageSelected]: template === temp,
})}
src={`image://${temp.name}.preview.jpg`}
width={140}
preview={false}
onClick={() => setSelectedTemplate(temp)}
/>
<Typography.Paragraph style={{ margin: 0, marginInlineStart: 5 }}>
{temp.displayName[locale]}
</Typography.Paragraph>
</Space>
))}
</Flex>
</Form.Item>
<Form.Item name={['fields', 'logo']} label='Logo'>
<Radio.Group>
{logos.map((logo) => (
<Radio.Button
style={{
padding: 12,
height: 'fit-content',
}}
key={logo}
value={logo}>
<Image src={`image://${logo}`} height={100} preview={false} />
</Radio.Button>
))}
</Radio.Group>
</Form.Item>
<Form.Item name={['fields', 'title']} label='Title'>
<Input type='text' placeholder='Enter value here' />
</Form.Item>
<Divider style={{ margin: '12px 0' }} />
<Form.Item>
<Typography.Title level={2} style={{ textDecoration: 'underline' }}>
{t('views:CreateInvoice.section.invoiceInformation')}
</Typography.Title>
</Form.Item>
{template?.fields.map((field) => (
<Form.Item
key={field.name}
name={['fields', field.name]}
label={field.displayName[locale]}>
<InvoiceInputField
type={field.type}
displayName={field.displayName[locale]}
/>
</Form.Item>
))}
<Divider style={{ margin: '12px 0' }} />
<Form.Item>
<Typography.Title level={2} style={{ textDecoration: 'underline' }}>
{t('views:CreateInvoice.section.invoiceItems')}
</Typography.Title>
</Form.Item>
<Form.Item name='items'>
<InputTable columnItems={template?.items} />
</Form.Item>
<Divider style={{ margin: '12px 0' }} />
<Form.Item>
<Typography.Title level={2} style={{ textDecoration: 'underline' }}>
{t('views:CreateInvoice.section.pageSettings')}
</Typography.Title>
</Form.Item>
<Form.Item name={['pageSettings', 'format']} label='Page Format'>
<Select
options={Object.values(PdfPageFormat).map((v) => ({
label: v,
value: v,
}))}
/>
</Form.Item>
<Form.Item label='Margins'>
<Flex justify='space-between'>
<Flex align='center' style={{ width: '24%' }}>
<Typography.Text
style={{ marginInlineEnd: 10, fontSize: 13, textWrap: 'nowrap' }}>
Top
</Typography.Text>
<Form.Item name={['pageSettings', 'margin', 'top']} noStyle>
<InputNumber
style={{ flexGrow: 1 }}
addonAfter={marginSuffixSelector}
min={0}
precision={1}
step={0.1}
placeholder='Enter value here'
/>
</Form.Item>
</Flex>
<Flex align='center' style={{ width: '24%' }}>
<Typography.Text
style={{ marginInlineEnd: 10, fontSize: 13, textWrap: 'nowrap' }}>
Bottom
</Typography.Text>
<Form.Item name={['pageSettings', 'margin', 'bottom']} noStyle>
<InputNumber
style={{ flexGrow: 1 }}
addonAfter={marginSuffixSelector}
min={0}
precision={1}
step={0.1}
placeholder='Enter value here'
/>
</Form.Item>
</Flex>
<Flex align='center' style={{ width: '24%' }}>
<Typography.Text
style={{ marginInlineEnd: 10, fontSize: 13, textWrap: 'nowrap' }}>
Left
</Typography.Text>
<Form.Item name={['pageSettings', 'margin', 'left']} noStyle>
<InputNumber
style={{ flexGrow: 1 }}
addonAfter={marginSuffixSelector}
min={0}
precision={1}
step={0.1}
placeholder='Enter value here'
/>
</Form.Item>
</Flex>
<Flex align='center' style={{ width: '24%' }}>
<Typography.Text
style={{ marginInlineEnd: 10, fontSize: 13, textWrap: 'nowrap' }}>
Right
</Typography.Text>
<Form.Item name={['pageSettings', 'margin', 'right']} noStyle>
<InputNumber
style={{ flexGrow: 1 }}
addonAfter={marginSuffixSelector}
min={0}
precision={1}
step={0.1}
placeholder='Enter value here'
/>
</Form.Item>
</Flex>
</Flex>
</Form.Item>
<Form.Item>
<Flex justify='space-between' align='center'>
<Button
type='default'
onClick={previewPdf}
style={{ marginInlineEnd: 20 }}>
{t('views:CreateInvoice.form.preview')}
</Button>
<Divider style={{ minWidth: 'auto', flexGrow: 1, borderWidth: 2 }} />
<Button
type='primary'
htmlType='submit'
style={{ marginInlineStart: 20 }}>
{t('views:CreateInvoice.form.submit')}
</Button>
</Flex>
</Form.Item>
{pdfDataUrl && (
<Form.Item>
<PdfViewerComponent
resourceUrl='https://cdn.syncfusion.com/ej2/23.1.40/dist/ej2-pdfviewer-lib'
documentPath={pdfDataUrl}
toolbarSettings={{
showTooltip: true,
toolbarItems: [
'PageNavigationTool',
'OrganizePagesTool',
'MagnificationTool',
'SelectionTool',
'PanTool',
'SearchOption',
'PrintOption',
],
}}
style={{ height: '93vh' }}>
<Inject
services={[
Toolbar,
Magnification,
Navigation,
Print,
TextSelection,
TextSearch,
]}
/>
</PdfViewerComponent>
</Form.Item>
)}
</Form>
);
}