flat-fuchsia
flat-fuchsia12mo ago

How to deal with a resource name that has a variable in it?

My resource name is something like categories/:id/posts this is a list of posts for a specific categories. How can I create a resources based on this url name convention?
11 Replies
kapa.ai
kapa.ai12mo ago
Hi @dipbazz. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- In refine, you can define your resources and their action paths in the <Refine> component under the resources property. This informs refine to use these paths when generating the breadcrumbs, menus, handling redirections, and inferring the current resource and action. For your case, you can define your resource as follows:
{
name: "posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
meta: {
canDelete: true,
},
}
{
name: "posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
meta: {
canDelete: true,
},
}
In the path definitions, :id is a placeholder for the actual id value. You can use the same :id notifier multiple times within the same route. Remember to assign a <Route /> for each path and an element to display at that path. The path specified in the resource definition should match the path specified in the route definition. Here is an example:
import { Refine } from "@refinedev/core";
import { PostList, PostCreate, PostEdit, PostShow } from "pages/posts";

const App: React.FC = () => {
return (
<Refine
resources={[
{
name: "posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
show: "/categories/:id/posts/show/:id",
meta: {
canDelete: true,
},
},
]}
>
<Routes>
<Route path="/categories/:id/posts">
<Route index element={<PostList />} />
<Route path="create" element={<PostCreate />} />
<Route path="edit/:id" element={<PostEdit />} />
<Route path="show/:id" element={<PostShow />} />
</Route>
</Routes>
</Refine>
);
};

export default App;
import { Refine } from "@refinedev/core";
import { PostList, PostCreate, PostEdit, PostShow } from "pages/posts";

const App: React.FC = () => {
return (
<Refine
resources={[
{
name: "posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
show: "/categories/:id/posts/show/:id",
meta: {
canDelete: true,
},
},
]}
>
<Routes>
<Route path="/categories/:id/posts">
<Route index element={<PostList />} />
<Route path="create" element={<PostCreate />} />
<Route path="edit/:id" element={<PostEdit />} />
<Route path="show/:id" element={<PostShow />} />
</Route>
</Routes>
</Refine>
);
};

export default App;
For more information, refer to the refine documentation (https://refine.dev/docs/tutorial/understanding-resources/index/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai12mo ago
<@494653850632978472> kapa.ai is still learning and improving, please let us know how it did by reacting below
flat-fuchsia
flat-fuchsiaOP12mo ago
@kapa.ai when I do this in my list page the query triggred will be on posts url but I want to trigger the url as categories/2/posts
kapa.ai
kapa.ai12mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To achieve this, you can create a new resource using the identity key to differentiate two URLs in Refine. Based on the params of the category, you can set filters in a useTable hook. Here's an example:
<Refine
resources={[
{
name: "posts",
identity: "posts",
list: "/posts",
},
{
name: "posts",
identity: "posts-from-categories",
list: "/categories/:categoryId/posts",
meta: {
hide: true
}
},
]}
/>
<Refine
resources={[
{
name: "posts",
identity: "posts",
list: "/posts",
},
{
name: "posts",
identity: "posts-from-categories",
list: "/categories/:categoryId/posts",
meta: {
hide: true
}
},
]}
/>
In your post page component's useTable hook, you can set the filters based on the categoryId as follows:
export const PostList = () => {
const { categoryId } = useParams();
useEffect(() => {
if (!!categoryId) {
setFilters([
{
field: "category_id",
operator: "eq",
value: categoryId
}
]);
} else {
setFilters([], "replace");
}
}, [categoryId])
}
export const PostList = () => {
const { categoryId } = useParams();
useEffect(() => {
if (!!categoryId) {
setFilters([
{
field: "category_id",
operator: "eq",
value: categoryId
}
]);
} else {
setFilters([], "replace");
}
}, [categoryId])
}
This solution was discussed in a Discord support thread (https://discord.com/channels/837692625737613362/1153268482620796948) and was confirmed as a good approach by the support staff. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai12mo ago
<@494653850632978472> kapa.ai is still learning and improving, please let us know how it did by reacting below
flat-fuchsia
flat-fuchsiaOP12mo ago
@kapa.ai I have a url as categories/:id/posts and I don't have access to posts url.
kapa.ai
kapa.ai12mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- In refine, you can define your resources and their action paths in the <Refine> component under the resources property. This informs refine to use these paths when generating the breadcrumbs, menus, handling redirections, and inferring the current resource and action. For your case, you can define your resource as follows:
{{
name: "categories/:id/posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
show: "/categories/:id/posts/show/:id",
meta: {{
canDelete: true,
}},
}}
{{
name: "categories/:id/posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
show: "/categories/:id/posts/show/:id",
meta: {{
canDelete: true,
}},
}}
In the path definitions, :id is a placeholder for the actual id value. You can use the same :id notifier multiple times within the same route. Remember to assign a <Route /> for each path and an element to display at that path. The path specified in the resource definition should match the path specified in the route definition. Here is an example:
import {{ Refine }} from "@refinedev/core";
import {{ PostList, PostCreate, PostEdit, PostShow }} from "pages/posts";

const App: React.FC = () => {{
return (
<Refine
resources={{[
{{
name: "categories/:id/posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
show: "/categories/:id/posts/show/:id",
meta: {{
canDelete: true,
}},
}},
]}}
>
<Routes>
<Route path="/categories/:id/posts">
<Route index element={{<PostList />}} />
<Route path="create" element={{<PostCreate />}} />
<Route path="edit/:id" element={{<PostEdit />}} />
<Route path="show/:id" element={{<PostShow />}} />
</Route>
</Routes>
</Refine>
);
}};

export default App;
import {{ Refine }} from "@refinedev/core";
import {{ PostList, PostCreate, PostEdit, PostShow }} from "pages/posts";

const App: React.FC = () => {{
return (
<Refine
resources={{[
{{
name: "categories/:id/posts",
list: "/categories/:id/posts",
create: "/categories/:id/posts/create",
edit: "/categories/:id/posts/edit/:id",
show: "/categories/:id/posts/show/:id",
meta: {{
canDelete: true,
}},
}},
]}}
>
<Routes>
<Route path="/categories/:id/posts">
<Route index element={{<PostList />}} />
<Route path="create" element={{<PostCreate />}} />
<Route path="edit/:id" element={{<PostEdit />}} />
<Route path="show/:id" element={{<PostShow />}} />
</Route>
</Routes>
</Refine>
);
}};

export default App;
For more information, refer to the refine documentation (https://refine.dev/docs/tutorial/understanding-resources/index/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai12mo ago
<@494653850632978472> kapa.ai is still learning and improving, please let us know how it did by reacting below
flat-fuchsia
flat-fuchsiaOP12mo ago
@kapa.ai, if I use my resource name as categories/:id/:posts my list page will hit an api endpoint with categories/:id/posts where the endpoint should be as categories/2/posts
kapa.ai
kapa.ai12mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- In refine, you can use the resource property on all data hooks to make a request to an API with a nested route. The resource property can be thought of as the URL. For example, if you want to make a request to the URL /categories/2/posts, you can use the useTable hook as follows:
import { useTable } from "@refinedev/core";

useTable({
resource: "/categories/2/posts",
});
import { useTable } from "@refinedev/core";

useTable({
resource: "/categories/2/posts",
});
This will make a request to the URL /categories/2/posts. However, if you want to make this dynamic based on the id, you would need to pass the id dynamically to the resource property. This can be done by getting the id from the route parameters or from the state. Here is an example of how you can do this:
import { useTable } from "@refinedev/core";
import { useParams } from "react-router-dom";

const { id } = useParams();

useTable({
resource: `/categories/${id}/posts`,
});
import { useTable } from "@refinedev/core";
import { useParams } from "react-router-dom";

const { id } = useParams();

useTable({
resource: `/categories/${id}/posts`,
});
In this example, useParams is a hook from react-router-dom that returns the dynamic parts of the route. For more information, refer to the refine documentation (https://refine.dev/docs/guides-concepts/faq#how-can-i-request-an-api-with-nested-route). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai12mo ago
<@494653850632978472> kapa.ai is still learning and improving, please let us know how it did by reacting below