flat-fuchsia
flat-fuchsia•2y 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.ai•2y 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.ai•2y 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.ai•2y ago
<@636120564561346571> kapa.ai is still learning and improving, please let us how it did by reacting below
flat-fuchsia
flat-fuchsia•2y 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}
wise-white
wise-white•2y ago
Hi, you can give resource and id pop to useForm to edit other resource in any page
flat-fuchsia
flat-fuchsia•2y 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>();
wise-white
wise-white•2y ago
like this
useForm({
refineCoreProps: {
action: "edit",
resource: "users",
id: 1,
}
});
useForm({
refineCoreProps: {
action: "edit",
resource: "users",
id: 1,
}
});
flat-fuchsia
flat-fuchsia•2y 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
wise-white
wise-white•2y ago
you can change reosurce to admin is this not work ? sorry i guess i don't quite understand
flat-fuchsia
flat-fuchsia•2y 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
wise-white
wise-white•2y 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 ?
flat-fuchsia
flat-fuchsia•2y 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}
wise-white
wise-white•2y ago
flat-fuchsia
flat-fuchsia•2y 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
wise-white
wise-white•2y ago
i guess i understand, you can use redirect:false and you can use onMutationSuccess to manually redirect any page
flat-fuchsia
flat-fuchsia•2y 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 ?
wise-white
wise-white•2y ago
I'm not quire sure yet but i will read again when i have time
flat-fuchsia
flat-fuchsia•2y ago
ok thank you and sorry to bother you 😅
wise-white
wise-white•2y 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 ?
flat-fuchsia
flat-fuchsia•2y ago
I tried but it doesn't change anything
wise-white
wise-white•2y ago
no. probably it's my fault to not understand
flat-fuchsia
flat-fuchsia•2y 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
wise-white
wise-white•2y 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.
flat-fuchsia
flat-fuchsia•2y 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
Omer•2y 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"
}
});
flat-fuchsia
flat-fuchsia•2y 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
Omer•2y 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.
flat-fuchsia
flat-fuchsia•2y ago
i'll try but i don't know if i will block by cors policy the api
flat-fuchsia
flat-fuchsia•2y 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
flat-fuchsia
flat-fuchsia•2y ago
I hope i'm a bit clearer 😅
Omer
Omer•2y 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});
};
flat-fuchsia
flat-fuchsia•2y 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
Omer•2y ago
mutate({
resource: "users",
id: id ?? "",
values: {...values}
})
mutate({
resource: "users",
id: id ?? "",
values: {...values}
})
you can try like this
flat-fuchsia
flat-fuchsia•2y ago
it remove the error but i always have the same issue 😫
Omer
Omer•2y 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
flat-fuchsia
flat-fuchsia•2y 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
eastern-cyan
eastern-cyan•2y 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.
flat-fuchsia
flat-fuchsia•2y 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