eastern-cyan
eastern-cyan7mo ago

How does one supported nested resource

Considering the following resources
const resources = [
{
name: "customers",
list: "/customers",
create: "/customers/create",
edit: "/customers/:id/edit",
show: "/customers/:id/show",
meta: {
canDelete: true,
},
},
{
name: "customer-products",
list: "/customers/:customer_id/products",
create: "/customers/:customer_id/products/create",
edit: "/customers/:customer_id/products/:id/edit",
show: "/customers/:customer_id/products/:id/show",
meta: {
canDelete: true,
},
options: {
hide: true,
},
},
];
const resources = [
{
name: "customers",
list: "/customers",
create: "/customers/create",
edit: "/customers/:id/edit",
show: "/customers/:id/show",
meta: {
canDelete: true,
},
},
{
name: "customer-products",
list: "/customers/:customer_id/products",
create: "/customers/:customer_id/products/create",
edit: "/customers/:customer_id/products/:id/edit",
show: "/customers/:customer_id/products/:id/show",
meta: {
canDelete: true,
},
options: {
hide: true,
},
},
];
How can this be achieved ? If I change from :customer_id to :id for list and create of customer-products then all is fine with the list and create functionality, but I can't use it for edit and show buttons. As it will be the same as the product_id, not the desired customer_id How do you deal with this problem ?
6 Replies
kapa.ai
kapa.ai7mo ago
Hi @i.stoica. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Refine supports route parameters defined with :param syntax. You can use these parameters in your action definitions and create your routes accordingly. For example, if you have a posts resource and you want to create a route for the show action of a specific post, you can define the show action as /posts/show/:id and use the id parameter in your component. Your action definitions in the resources can contain additional parameters and nested routes. Passing these parameters when navigating to the pages are handled by the current available parameters and the meta props of the related hooks and components. However, based on the information provided in the extracts, it seems that Refine does not directly support nested resources in the way you're trying to implement them. The :id parameter is typically used to identify a specific resource, not a parent resource. One possible workaround could be to store the selected :store_id (from a Select input, for example), and passing it as a parameter to the resource. This would likely involve creating a Custom Page and implementing the API request with axios or something similar. For more information, you can refer to the Refine documentation on routing (https://refine.dev/docs/routing/integrations/react-router#usage-with-a-root-route) and Refine documentation on Remix (https://refine.dev/docs/routing/integrations/remix#usage). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7mo ago
<@180601470268211200> kapa.ai is still learning and improving, please let us know how it did by reacting below
eastern-cyan
eastern-cyan7mo ago
The example shown has resources at same level, no nesting
correct-apricot
correct-apricot6mo ago
@i.stoica Hi, I'm having the same problem, did you manage to find a solution?
flat-fuchsia
flat-fuchsia6mo ago
Has anyone tried nested resources with nextJS Router "@refinedev/nextjs-router" ? Any references/example will be super helpful.
eastern-cyan
eastern-cyan5mo ago
Yes, nesting the routing and the using a custom parameter extractor with useMatch - I think it is very ugly but works - if anyoneelse knows a better way (except Kappa :D)
const { resource } = useResource();
const match = useMatch(`${resource?.edit}`);
const customer_id = match?.params.customer_id ?? "";
const product_id = match?.params.product_id ?? "";
const meta = useMemo(
() => ({
customer_id,
product_id,
}),
[customer_id, product_id]
);

const { data: customer, isLoading: customerIsLoading } = useOne({
resource: "customers",
id: customer_id,
});
const { resource } = useResource();
const match = useMatch(`${resource?.edit}`);
const customer_id = match?.params.customer_id ?? "";
const product_id = match?.params.product_id ?? "";
const meta = useMemo(
() => ({
customer_id,
product_id,
}),
[customer_id, product_id]
);

const { data: customer, isLoading: customerIsLoading } = useOne({
resource: "customers",
id: customer_id,
});