adverse-sapphire
adverse-sapphire13mo ago

Problems nesting resources and routes

I am trying to nest my child resource routes within the parents, but I am having difficulty doing so. The first I am having is that each resource object expects the parameter :id. This means if I have a nested resource I cant use :id because its already taken by the parent. The second issue is that, even if I don't need to use :id, for example, in my nested create route, the page wont load the element anyways. By this I mean, at the route /courses/show/:id/scenarios/create, it will just continue to display the /courses/show/:id page. I am using react router v6 for my routing. Here is my resources configuration, any help would be appreciated:
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:id",
show: "/courses/show/:id",
},
{
name: "scenarios",
list: "/courses/show/:id",
create: "/courses/show/:id/scenarios/create",
edit: "/courses/show/:id/scenarios/edit/:scenarioId",
show: "/courses/show/:id/scenarios/show/:scenarioId",
meta: {
parent: "courses",
hide: true,
},
},
]}
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:id",
show: "/courses/show/:id",
},
{
name: "scenarios",
list: "/courses/show/:id",
create: "/courses/show/:id/scenarios/create",
edit: "/courses/show/:id/scenarios/edit/:scenarioId",
show: "/courses/show/:id/scenarios/show/:scenarioId",
meta: {
parent: "courses",
hide: true,
},
},
]}
14 Replies
kapa.ai
kapa.ai13mo ago
Hi @.chasel. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Refine supports nested routes and parameters in your resources. You can define parameters using the :param syntax. For nested resources, you can use different parameter names to avoid conflicts. In your case, you can use :courseId for courses and :scenarioId for scenarios. Here's how you can modify your resources configuration:
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:courseId",
show: "/courses/show/:courseId",
},
{
name: "scenarios",
list: "/courses/show/:courseId/scenarios",
create: "/courses/show/:courseId/scenarios/create",
edit: "/courses/show/:courseId/scenarios/edit/:scenarioId",
show: "/courses/show/:courseId/scenarios/show/:scenarioId",
meta: {
parent: "courses",
hide: true,
},
},
]}
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:courseId",
show: "/courses/show/:courseId",
},
{
name: "scenarios",
list: "/courses/show/:courseId/scenarios",
create: "/courses/show/:courseId/scenarios/create",
edit: "/courses/show/:courseId/scenarios/edit/:scenarioId",
show: "/courses/show/:courseId/scenarios/show/:scenarioId",
meta: {
parent: "courses",
hide: true,
},
},
]}
As for the issue of the page not loading the element, it might be due to how your routes are structured in your router. Make sure that your routes are correctly nested and that the parent route includes an <Outlet /> component where the child routes will be rendered. For more information, you can refer to the Refine documentation on React Router v6 (https://refine.dev/docs/packages/documentation/routers/react-router-v6) and the Refine migration guide (https://refine.dev/docs/migration-guide/3x-to-4x). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai13mo ago
<@196423433930670080> kapa.ai is still learning and improving, please let us how it did by reacting below
adverse-sapphire
adverse-sapphire13mo ago
@kapa.ai I cannot use courseId and scenarioId because refine will throw an error saying that it expects the parameter :id atleast once for each resource.
kapa.ai
kapa.ai13mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- I see, refine expects the :id parameter for each resource. In this case, you can still use nested routes, but you'll need to handle the id parameter carefully. For the scenarios resource, you can use the :id parameter to represent the scenarioId. To get the courseId, you can use the useParsed hook which allows you to access the URL and query parameters along with the inferred resource, action and id from the URL. Here's how you can modify your resources configuration:
resources={{[
{{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:id",
show: "/courses/show/:id",
}},
{{
name: "scenarios",
list: "/courses/show/:id/scenarios",
create: "/courses/show/:id/scenarios/create",
edit: "/courses/show/:id/scenarios/edit/:id",
show: "/courses/show/:id/scenarios/show/:id",
meta: {{
parent: "courses",
hide: true,
}},
}},
]}}
resources={{[
{{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:id",
show: "/courses/show/:id",
}},
{{
name: "scenarios",
list: "/courses/show/:id/scenarios",
create: "/courses/show/:id/scenarios/create",
edit: "/courses/show/:id/scenarios/edit/:id",
show: "/courses/show/:id/scenarios/show/:id",
meta: {{
parent: "courses",
hide: true,
}},
}},
]}}
And here's how you can use the useParsed hook to get the courseId:
import { useParsed } from "@refinedev/core";

const MyComponent = () => {
const {
id: courseId,
} = useParsed();

/* ... */
};
import { useParsed } from "@refinedev/core";

const MyComponent = () => {
const {
id: courseId,
} = useParsed();

/* ... */
};
In this example, courseId will hold the id from the /courses/show/:id route. For more information, you can refer to the Refine documentation on useParsed (https://refine.dev/docs/api-reference/core/hooks/navigation/useParsed). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai13mo ago
<@196423433930670080> kapa.ai is still learning and improving, please let us how it did by reacting below
adverse-sapphire
adverse-sapphire13mo ago
@kapa.ai I am using this resources object now
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:course_id",
show: "/courses/show/:course_id",
},
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:course_id",
show: "/courses/show/:course_id",
},
and it is not throwing errors but course_id url param is not resolving to a value when I click the course edit or show button.
kapa.ai
kapa.ai13mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Refine expects the :id parameter for each resource. If you use a different parameter name like :course_id, it won't be able to resolve it. When you click the edit or show button, refine uses the :id parameter to generate the correct URL. If you use :course_id instead, refine won't be able to find the value for this parameter, and the URL won't be generated correctly. Here's how you should define your resources:
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:id",
show: "/courses/show/:id",
},
// ...
]}
resources={[
{
name: "courses",
list: "/courses",
create: "/courses/create",
edit: "/courses/edit/:id",
show: "/courses/show/:id",
},
// ...
]}
And here's how you can use the ShowButton or EditButton:
import { ShowButton } from "@refinedev/antd";

const MyShowComponent = () => {
return (
<ShowButton
resource="courses"
recordItemId="123"
/>
);
};
import { ShowButton } from "@refinedev/antd";

const MyShowComponent = () => {
return (
<ShowButton
resource="courses"
recordItemId="123"
/>
);
};
In this example, clicking the button will trigger the show method of useNavigation and then redirect the app to the show action path of the resource, filling the necessary parameters in the route. The recordItemId prop is used to provide the :id parameter value. For more information, you can refer to the Refine documentation on ShowButton (https://refine.dev/docs/api-reference/antd/components/buttons/show-button) and EditButton (https://refine.dev/docs/api-reference/antd/components/buttons/edit-button). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai13mo ago
<@196423433930670080> kapa.ai is still learning and improving, please let us how it did by reacting below
adverse-sapphire
adverse-sapphire13mo ago
@kapa.ai Can I modify the edit button parameters to resolve a unique id in the url parameters?
kapa.ai
kapa.ai13mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, you can modify the EditButton parameters to resolve a unique id in the URL parameters. The EditButton component has a recordItemId prop that is used to append the record id to the end of the route path for the edit route. Here's an example of how you can use it:
import { EditButton } from "@refinedev/antd";

const MyEditComponent = () => {
return (
<EditButton
resource="courses"
recordItemId="123"
/>
);
};
import { EditButton } from "@refinedev/antd";

const MyEditComponent = () => {
return (
<EditButton
resource="courses"
recordItemId="123"
/>
);
};
In this example, clicking the button will trigger the edit method of useNavigation and then redirect the app to the edit action path of the resource, filling the necessary parameters in the route. The recordItemId prop is used to provide the :id parameter value. For more information, you can refer to the Refine documentation on EditButton (https://refine.dev/docs/api-reference/antd/components/buttons/edit-button). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai13mo ago
<@196423433930670080> kapa.ai is still learning and improving, please let us how it did by reacting below
adverse-sapphire
adverse-sapphire13mo ago
@kapa.ai No i would like the EditButton to resolve :course_id in the url parameters not :id. This seems like an oversight in refine
kapa.ai
kapa.ai13mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- I understand your requirement, but currently, Refine expects the :id parameter for each resource. If you use a different parameter name like :course_id, it won't be able to resolve it. When you click the edit or show button, Refine uses the :id parameter to generate the correct URL. If you use :course_id instead, Refine won't be able to find the value for this parameter, and the URL won't be generated correctly. This is not an oversight in React, but rather a design decision in Refine to standardize the parameter name across all resources. If you need more flexibility in defining your routes, you might need to extend or customize the Refine components or use a different routing library that allows more flexibility in defining route parameters. For more information, you can refer to the Refine documentation (https://refine.dev/docs). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai13mo ago
<@196423433930670080> kapa.ai is still learning and improving, please let us how it did by reacting below