rare-sapphire
rare-sapphire15mo ago

Change url between list and edit

Hi erveyone !! actually I have an endpoint which return me all admin user (myUrl/api/admins) and to edit these a user i need to patch on an other endpoint (myUrl/api/user/{id}). {id} is the id of the user i need to edit. I would like to know if it is possible to use an endpoint for the list view and an other for editing and if it is, how can do that ? Thank you guys !!
38 Replies
kapa.ai
kapa.ai15mo ago
Hey @harisris! I'm the kapa.ai support bot. I've searched through the docs to try to answer your question. :wave:
kapa.ai
kapa.ai15mo ago
---------------------- Hi there! It is possible to use different endpoints for the list view and edit view. You can do this by using the edit method of the useNavigation (https://refine.dev/docs/api-reference/core/hooks/navigation/useNavigation/) hook. For example, you can use the EditButton component from the @pankod/refine package to create a button that will redirect to the edit page of a particular post. You can use the resourceName property to specify the endpoint for the list view, and the recordItemId property to specify the ID of the post you want to edit.
import { EditButton } from "@pankod/refine";

export const MyEditComponent = () => {
return <EditButton resourceName="categories" recordItemId="2" />;
};
import { EditButton } from "@pankod/refine";

export const MyEditComponent = () => {
return <EditButton resourceName="categories" recordItemId="2" />;
};
Clicking the button will trigger the edit method of useNavigation (https://refine.dev/docs/api-reference/core/hooks/navigation/useNavigation/) and then redirect the app to /categories/edit/2. You can also use the EditButton component from the @pankod/refine-antd and @pankod/refine-mantine packages, which have the same properties as the EditButton component from the @pankod/refine package. I hope this helps! ----------------------
useNavigation | refine
useNavigation is a hook that provides methods to navigate the app. Internally, it uses the go method of the routerProvider.
kapa.ai
kapa.ai15mo ago
<@636120564561346571> kapa.ai is still learning and improving, please let us how it did by reacting below
rare-sapphire
rare-sapphire15mo ago
I try to add this code to the columns of my list view but it doesn't work :
{
field: "actions",
headerName: translate("table.actions"),
minWidth: 250,
renderCell: function render(params) {
return (
<>
<ShowButton hideText recordItemId={params.row.id} resource="users" />
<EditButton hideText recordItemId={params.row.id} resource="users" />
</>
);
}
}
{
field: "actions",
headerName: translate("table.actions"),
minWidth: 250,
renderCell: function render(params) {
return (
<>
<ShowButton hideText recordItemId={params.row.id} resource="users" />
<EditButton hideText recordItemId={params.row.id} resource="users" />
</>
);
}
}
it call the /admin/{id} endpoint instead of /users/{id}
exotic-emerald
exotic-emerald15mo ago
Hi, you can give resource and id pop to useForm to edit other resource in any page
rare-sapphire
rare-sapphire15mo ago
Hi Alican thank you for your answer !! Should i add it like that ?
<Edit
resource="users"
isLoading={formLoading}
saveButtonProps={{onClick: handleSubmit(handleSubmitUsersEdit)}}
<Edit
resource="users"
isLoading={formLoading}
saveButtonProps={{onClick: handleSubmit(handleSubmitUsersEdit)}}
or add it here ?
const {
refineCore: {onFinish, formLoading},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>();
const {
refineCore: {onFinish, formLoading},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>();
exotic-emerald
exotic-emerald15mo ago
like this
useForm({
refineCoreProps: {
action: "edit",
resource: "users",
id: 1,
}
});
useForm({
refineCoreProps: {
action: "edit",
resource: "users",
id: 1,
}
});
rare-sapphire
rare-sapphire15mo ago
when i try to edit a user, i have an api call to fetch current user data from same endpoint (from /admin/{id}, I've put record?.id as id value to get current user id
exotic-emerald
exotic-emerald15mo ago
you can change reosurce to admin is this not work ? sorry i guess i don't quite understand
rare-sapphire
rare-sapphire15mo ago
the initial ressource is admin (the one that i put in <Refine/> component) and i would like to edit users that i fetch from admin endpoint in the user endpoint. To do that i need the currect id from admin endpoint to edit in user endpoint. (all admin user are in the users ressources) @alicanerdurmaz
exotic-emerald
exotic-emerald15mo ago
BASE_URL = myUrl/api this will send request to myUrl/api/users/1
useForm({
refineCoreProps: {
action: "edit",
resource: "users",
id: 1,
}
});
useForm({
refineCoreProps: {
action: "edit",
resource: "users",
id: 1,
}
});
this will send request to myUrl/api/admin/1
useForm({
refineCoreProps: {
action: "edit",
resource: "admin",
id: 1,
}
});
useForm({
refineCoreProps: {
action: "edit",
resource: "admin",
id: 1,
}
});
this will send request to myUrl/api/admin/users/1
useForm({
refineCoreProps: {
action: "edit",
resource: "admin/users",
id: 1,
}
});
useForm({
refineCoreProps: {
action: "edit",
resource: "admin/users",
id: 1,
}
});
is this not work for your needs ?
rare-sapphire
rare-sapphire15mo ago
const {
refineCore: {onFinish, formLoading},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>({
refineCoreProps: {
action: "edit",
resource: "users",
id: record?.id
}
});
const {
refineCore: {onFinish, formLoading},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>({
refineCoreProps: {
action: "edit",
resource: "users",
id: record?.id
}
});
I've done that and it should redirect me to the following url : myUrl/api/users/{record?.id} but the url of the request that made refine is : myUrl/api/admins/{record?.id}
exotic-emerald
exotic-emerald15mo ago
rare-sapphire
rare-sapphire15mo ago
i find that in the doc but i need also to change the request url and the code that i find in the doc do not change the request url in my case i'll try to explicite my issue a bit more precisely
exotic-emerald
exotic-emerald15mo ago
i guess i understand, you can use redirect:false and you can use onMutationSuccess to manually redirect any page
rare-sapphire
rare-sapphire15mo ago
actually i have an endpoint which is myUrl/api/admin wich only serves me in the list view. I have also an other endpoint which is myUrl/api/users which i want to use in edit and view mode. When edit in the list view, i would like to edit or view the user the select users but on the myUrl/api/users endpoint. (of course IDs are the same between the 2 endpoints and the users endpoint contain all users who are in admins endpoint). In other word in I need to change the resources depending on whether I am in view or edition view or if I am in list view. I try code snippets you send before but that not work for me. Maybe i use it in a wrong way @alicanerdurmaz is it what you understand from my previous explanations ?
exotic-emerald
exotic-emerald15mo ago
I'm not quire sure yet but i will read again when i have time
rare-sapphire
rare-sapphire15mo ago
ok thank you and sorry to bother you 😅
exotic-emerald
exotic-emerald15mo ago
you can use redirect:false and you can use onMutationSuccess to manually redirect any page
you can use redirect:false and you can use onMutationSuccess to manually redirect any page
is this not work for you ?
rare-sapphire
rare-sapphire15mo ago
I tried but it doesn't change anything
exotic-emerald
exotic-emerald15mo ago
no. probably it's my fault to not understand
rare-sapphire
rare-sapphire15mo ago
maybe i implemented it wrong where should i do it ? In list component or in edit component ? I think that it should be in list view but i don't have any useForm in my list component
export const AdminsList: React.FC = () => {

const {dataGridProps} = useDataGrid<IUsers>();

const {
paginationMode,
onPageChange,
pageSize,
onPageSizeChange,
...restDataGridProps
} = dataGridProps;

const translate = useTranslate();


const columns: GridColumns = [
// ...
// all my columns
{
field: "actions",
headerName: translate("table.actions"),
minWidth: 250,
renderCell: function render(params) {
return (
<>
<ShowButton hideText recordItemId={params.row.id} resource="users" />
<EditButton hideText recordItemId={params.row.id} resource="users" />
</>
);
}
}
];


return (
<>
<Header pageTitle={"users.users"} />
<List
title=""
wrapperProps={{
sx: {
"-webkit-box-shadow": "none",
"-moz-box-shadow": "none",
"box-shadow": "none"
}
}}>
<DataGrid
{...restDataGridProps}
paginationMode="server"
onPageChange={onPageChange}
pageSize={30}
columns={columns}
autoHeight
/>
</List>
</>
);
};
export const AdminsList: React.FC = () => {

const {dataGridProps} = useDataGrid<IUsers>();

const {
paginationMode,
onPageChange,
pageSize,
onPageSizeChange,
...restDataGridProps
} = dataGridProps;

const translate = useTranslate();


const columns: GridColumns = [
// ...
// all my columns
{
field: "actions",
headerName: translate("table.actions"),
minWidth: 250,
renderCell: function render(params) {
return (
<>
<ShowButton hideText recordItemId={params.row.id} resource="users" />
<EditButton hideText recordItemId={params.row.id} resource="users" />
</>
);
}
}
];


return (
<>
<Header pageTitle={"users.users"} />
<List
title=""
wrapperProps={{
sx: {
"-webkit-box-shadow": "none",
"-moz-box-shadow": "none",
"box-shadow": "none"
}
}}>
<DataGrid
{...restDataGridProps}
paginationMode="server"
onPageChange={onPageChange}
pageSize={30}
columns={columns}
autoHeight
/>
</List>
</>
);
};
here is my list component
exotic-emerald
exotic-emerald15mo ago
Edit and Show buttons for page navigation. if you wanna edit resource in list view. you can check useEditableTable https://refine.dev/docs/api-reference/antd/hooks/table/useEditableTable/ or you can open your form in modal.
rare-sapphire
rare-sapphire15mo ago
i don't want to edit in the list view i just want to specify the url it sould not use the usual url but an other. I found that in the doc but it doesn't work for me (https://refine.dev/docs/api-reference/mui/components/buttons/edit-button/#resourcenameorroutename-). I thought that the modifification should be done in the list component but i don't have useForm in this component. So i do it in the edit component but it doesn't work
Edit | refine
uses Material UI component. It uses the edit method from useNavigation under the hood. It can be useful to redirect the app to the edit page route of resource.
Omer
Omer15mo ago
Hey @harisris , Can you check this doc? https://refine.dev/docs/faq/#how-can-i-request-an-api-with-nested-route
const {
refineCore: {onFinish, formLoading},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>({
refineCoreProps: {
resource: "ANY_PATH_YOUR_API"
}
});
const {
refineCore: {onFinish, formLoading},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>({
refineCoreProps: {
resource: "ANY_PATH_YOUR_API"
}
});
rare-sapphire
rare-sapphire15mo ago
Hey @Omer nested-route are not appropriate for my case and i've try this code snippet but it doesn't work for me i've put this code in my edit component. Should i do in an other component ?
Omer
Omer15mo ago
Please share clearly what happened when you try the thing you want to do with me and the method we suggested. It should be a CodeSandbox or StackBlitz environment. Otherwise, we cannot help you. Thank you for your understanding.
rare-sapphire
rare-sapphire15mo ago
i'll try but i don't know if i will block by cors policy the api
rare-sapphire
rare-sapphire15mo ago
I've made the stackblitz but I'm blocked by the cors policy. But it will be easier to understand. (https://stackblitz.com/edit/react-ts-dbdb2s?file=admins/list.tsx) In the list component (line 67 & 68) I specified the ressources as i found in the doc but it doesn't work for me. I also try to do it in the edit in the useForm as you send earlier, but it also do not work. My problem is that actulally my api target this url https://api.localhost/api/admins/2ff1e2a5-2b24-44a2-a71d-edc4ede7b59e but i would like to change the url to https://api.localhost/api/users/2ff1e2a5-2b24-44a2-a71d-edc4ede7b59e because the admins endpoint only serves me for the list component. For the edit and the show i need to use the users endpoint. The ressource specified in the App component is admins
StackBlitz
React Ts (forked) - StackBlitz
React + TypeScript starter project
rare-sapphire
rare-sapphire15mo ago
I hope i'm a bit clearer 😅
Omer
Omer15mo ago
You can use useUpdate hook. https://refine.dev/docs/api-reference/core/hooks/data/useUpdate/
const { mutate } = useUpdate();

const {
refineCore: {onFinish, formLoading, id},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>();

const handleSubmitUsersEdit = (values: FieldValues) => {
values.roles = stringToTab(selected);
values.contact.mobile_phone_number = removeSpaces(mobilePhone);
values.contact.landline_phone_number = removeSpaces(landlinePhone);
if (language === "fr-FR") {
values.contact.language = "fr";
}

mutate({
resource: "users",
id,
values: {...values}
})
//onFinish({...values});
};
const { mutate } = useUpdate();

const {
refineCore: {onFinish, formLoading, id},
register,
handleSubmit,
control,
formState: {errors}
} = useForm<IUsers>();

const handleSubmitUsersEdit = (values: FieldValues) => {
values.roles = stringToTab(selected);
values.contact.mobile_phone_number = removeSpaces(mobilePhone);
values.contact.landline_phone_number = removeSpaces(landlinePhone);
if (language === "fr-FR") {
values.contact.language = "fr";
}

mutate({
resource: "users",
id,
values: {...values}
})
//onFinish({...values});
};
rare-sapphire
rare-sapphire15mo ago
i'll try @Omer thank you it said to me : Type 'BaseKey | undefined' is not assignable to type 'BaseKey'.   Type 'undefined' is not assignable to type 'BaseKey'. Is it normal
Omer
Omer15mo ago
mutate({
resource: "users",
id: id ?? "",
values: {...values}
})
mutate({
resource: "users",
id: id ?? "",
values: {...values}
})
you can try like this
rare-sapphire
rare-sapphire15mo ago
it remove the error but i always have the same issue 😫
Omer
Omer15mo ago
I understand that you are new to React and perhaps to programming in general, and I really appreciate that. Unfortunately, we cannot provide further assistance. You can try to solve your problems by reviewing Refine documentation and examples, or you can seek help from other community members. Thank you for your understanding. Lastly, you can review our real-world example where you may find answers to many of your questions. https://github.com/refinedev/real-world-example
GitHub
GitHub - refinedev/real-world-example: Exemplary real world applica...
Exemplary real world application built with refine - GitHub - refinedev/real-world-example: Exemplary real world application built with refine
rare-sapphire
rare-sapphire15mo ago
If i understand right, the handleSubmitUsersEdit is used to change the data before submited to the api and id trigger on save button click? so why should do something in this function ?? @Omer I don't know if you really understand my issue but my goal is to have a ressource for the list (which i specified in the App component admins) and an other ressources for the edit and the view (users). the list have to target this endpoint https://api.localhost/api/admins (it actually works) and the edit and the view have to target https://api.localhost/api/users/id. How can I do that ? Because when i click on edit button in my list component, it fetch data from https://api.localhost/api/admins
molecular-blue
molecular-blue15mo ago
Hey @haribo_mushi , you can use useOne hook to get the data you need and use it. https://refine.dev/docs/api-reference/core/hooks/data/useOne/ Please go through our documentation, it will help you a lot.
useOne | refine
useOne is an extended version of TanStack Query's useQuery. It supports all the features of useQuery and adds some extra features.
rare-sapphire
rare-sapphire14mo ago
Finally i solved my issue like that
const {dataGridProps} = useDataGrid<IUsers>({
resource: "admins",
});
const {dataGridProps} = useDataGrid<IUsers>({
resource: "admins",
});
in my admin/list.tsx and in my App.tsx i've change the ressource from admins to users and it work perfectly