Update Element
We have looked for Displaying, Adding, Deleting element before. Now, It's time to deal with Update Element.
Create Page
Like Displaying element, Edit element also comes with element id at the end of URL.
For example, Let's consider about Article element.
To display specific article, we need to navigate URL like this /article/[article_id].
Edit Article also applies same concept.
Thus, we need to create Page for edit article in this folder pages/article/edit/[id].tsx
Regarding Creating page, you can refer it here
import { AppHead } from '@components';
import { EditArticle } from 'modules/Articles/PagesContainer/EditArticle';
import { useRouter } from 'next/router';
import { FC } from 'react';
import MainLayout from '../../../components/layouts/MainLayout';
type PageComponent = FC & { layout: typeof MainLayout };
const EditArticlePage: PageComponent = () => {
const router = useRouter();
const { id } = router.query;
return (
<>
<AppHead title="Bee V2" />
<EditArticle router={router} id={id!} />
</>
);
};
EditArticlePage.layout = MainLayout;
export default EditArticlePage;
Modularize for each tables
You can define each modules in modules directory in root folder.
We put EditArticle component inside /modules/Articles/PageContainer/EditArticle.tsx.
When component is loaded, we fetch details info of article by using GraphQL queries with react hook useGetArticleByIdQuery.
Once data fetched from GraphQL server, it renders EditArticleForm component while passing article data as its' props
<StyledPageContent>
{data && !isLoading ? (
<EditArticleForm articleId={id} details={data?.article} />
) : (
<ContentSpin />
)}
</StyledPageContent>
Display data and/or steps for edit article
For Article there are several steps to input data but for other elements, it might not exist several steps.
Some element can be filled with only one step of form.
So in that case, you don't need to display several steps.
details is the variable that comes from EditArticleForm props.
We can set form value with this variable but we need to consider to remove some unnecessary fields like created, modified before set form value to prevent possible error while passing form data as a param of updateArticleMutation.
Because, some fileds like created or modified is the field that does not exist in GraphQL shecma for update element.
So if we pass those variable while executing update mutation, it might cause an error.
useEffect(() => {
const tmp_details = { ...details };
delete tmp_details['id'];
delete tmp_details['created'];
delete tmp_details['modified'];
form.setFieldsValue(tmp_details);
if (updateLoading) {
showInfo(t('messages:info-update-wip'));
}
}, [updateLoading]);
return (
<StyledForm>
<Form form={form} scrollToFirstError>
<AddArticleStep1 />
<AddArticleStep2 />
<AddArticleStep3 />
<div style={{ textAlign: 'right' }}>
<Space>
<Button onClick={() => onFinish()} type="primary">
{t('actions:update')}
</Button>
<Button onClick={() => router.back()}>{t('actions:cancel')}</Button>
</Space>
</div>
</Form>
</StyledForm>
);
Update data
Once user click update button it will invoke onFinish() handler.
In this function, it will validate form data and will execute updateArticleMutation like this
const {
mutate,
isLoading: updateLoading,
data
} = useUpdateArticleMutation<Error>(graphqlRequestClient, {
onSuccess: (
data: UpdateArticleMutation,
_variables: UpdateArticleMutationVariables,
_context: any
) => {
router.push(`/article/${data.updateArticle?.id}`);
showSuccess(t('messages:success-updated'));
},
onError: (error) => {
showError(t('messages:error-update-data'));
}
});
const updateArticle = ({ id, input }: UpdateArticleMutationVariables) => {
mutate({ id, input });
};
const onFinish = () => {
form.validateFields()
.then(() => {
updateArticle({
id: articleId,
input: { ...form.getFieldsValue(true), accountId: 1 }
});
})
.catch((err) => showError(t('messages:error-update-data')));
};
Finally Article data will be updated you will redirect to the Article detail page. That's it !