xenial-black
xenial-black7mo ago

Pass Resource directly to go / useGo

In the documentation for useGo / go ( https://refine.dev/docs/routing/hooks/use-go/#with-resource ) it says that you can pass a resource to the to param of go. @kapa.ai can you think of an example on getting a resource and passing it to go?
17 Replies
kapa.ai
kapa.ai7mo ago
Hi @bastianwegge. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Sure, I can provide an example based on the information extracted from the documentation. In the useGo hook, you can pass a resource object to the to parameter. This object can contain the resource name or identifier, the action, and optionally an id and meta data. The routerProvider will convert this resource object into the path defined in the resources array within the <Refine /> component. Here's an example of how you can use it:
import { useGo } from "@refinedev/core";

const MyComponent = () => {
const go = useGo();

return (
<Button
onClick={() => {
go({
to: {
resource: "posts", // resource name or identifier
action: "edit",
id: "1",
}
query: {
foo: "bar",
},
type: "push",
});
}}
>
Go Posts With Default Filters
</Button>
);
};
import { useGo } from "@refinedev/core";

const MyComponent = () => {
const go = useGo();

return (
<Button
onClick={() => {
go({
to: {
resource: "posts", // resource name or identifier
action: "edit",
id: "1",
}
query: {
foo: "bar",
},
type: "push",
});
}}
>
Go Posts With Default Filters
</Button>
);
};
In this example, when the button is clicked, it will navigate to the edit page of the post with id "1". The query parameter is used to pass additional parameters to the path. You can also pass meta properties when using useGo's go function with to as a resource object. This allows you to pass additional path parameters to the path defined in the resources array within the <Refine /> component. Here's an example:
import { useGo } from "@refinedev/core";

const MyButton = () => {
const go = useGo();

return (
<Button
onClick={() => {
go({
to: {
resource: "posts",
action: "edit",
id: "1",
meta: {
foo: "bar",
},
},
type: "push",
});
// generated path will be "/bar/posts/1/edit"
}}
>
Go Posts
</Button>
);
};
import { useGo } from "@refinedev/core";

const MyButton = () => {
const go = useGo();

return (
<Button
onClick={() => {
go({
to: {
resource: "posts",
action: "edit",
id: "1",
meta: {
foo: "bar",
},
},
type: "push",
});
// generated path will be "/bar/posts/1/edit"
}}
>
Go Posts
</Button>
);
};
In this example, the meta property is used to pass the "foo" parameter to the path. The generated path will be "/bar/posts/1/edit". Sources: - useGo Documentation (https://refine.dev/docs/routing/hooks/use-go/) - GitHub PR (https://github.com/refinedev/refine/pull/5452) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7mo ago
<@317433576721219584> kapa.ai is still learning and improving, please let us know how it did by reacting below
xenial-black
xenial-black7mo ago
@kapa.ai The documentation says Also, you can pass a resource object to the to parameter. The routerProvider will convert the resource object to the path. So I'd like to pass a IResourceItem into the to argument. Can you think of an example on how to do that?
kapa.ai
kapa.ai7mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Sure, you can pass an IResourceItem object to the to parameter of the go function from useGo hook. First, you need to get the resource using the useResource hook. Here's an example:
import { useGo, useResource } from "@refinedev/core";

const MyComponent = () => {
const go = useGo();
const { resource } = useResource();

return (
<Button
onClick={() => {
go({
to: resource,
type: "push",
});
}}
>
Go to Resource
</Button>
);
};
import { useGo, useResource } from "@refinedev/core";

const MyComponent = () => {
const go = useGo();
const { resource } = useResource();

return (
<Button
onClick={() => {
go({
to: resource,
type: "push",
});
}}
>
Go to Resource
</Button>
);
};
In this example, when the button is clicked, it will navigate to the path defined by the current resource. Please note that the useResource hook returns the current resource based on the route. If you want to navigate to a specific resource, you need to get that resource from the resources array returned by useResource. Sources: - useGo Documentation (https://refine.dev/docs/routing/hooks/use-go/) - useResource Documentation (https://refine.dev/docs/routing/hooks/use-resource) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7mo ago
<@317433576721219584> kapa.ai is still learning and improving, please let us know how it did by reacting below
xenial-black
xenial-black7mo ago
@kapa.ai is there something like a LinkToResource which would make this process easier?
kapa.ai
kapa.ai7mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, there is a component called NavigateToResource that can be used to navigate to a specific resource page. This component is part of the @refinedev/remix-router, @refinedev/react-router-v6, and @refinedev/nextjs-router packages. Here's an example of how you can use it:
import { NavigateToResource } from "@refinedev/remix-router";

export default function IndexPage() {
return <NavigateToResource />;
}
import { NavigateToResource } from "@refinedev/remix-router";

export default function IndexPage() {
return <NavigateToResource />;
}
In this example, the NavigateToResource component will redirect to the first list route in the resources array if no resource is provided. You can also specify a resource and meta data:
import { NavigateToResource } from "@refinedev/remix-router";

export default function IndexPage() {
return <NavigateToResource resource="posts" meta={{ foo: "bar" }} />;
}
import { NavigateToResource } from "@refinedev/remix-router";

export default function IndexPage() {
return <NavigateToResource resource="posts" meta={{ foo: "bar" }} />;
}
In this example, the NavigateToResource component will redirect to the list route of the "posts" resource. Sources: - Remix Router Documentation (https://refine.dev/docs/routing/integrations/remix#additional-components) - React Router v6 Documentation (https://refine.dev/docs/routing/integrations/react-router#additional-components) - Next.js Router Documentation (https://refine.dev/docs/routing/integrations/next-js#pages-directory) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7mo ago
<@317433576721219584> kapa.ai is still learning and improving, please let us know how it did by reacting below
rising-crimson
rising-crimson7mo ago
Hey @bastianwegge you dont need to pass whole resource object. We are already doing it based on the provided identifier. Also resource object unnecessary because you also need to provide action and id (for edit, show etc..)
xenial-black
xenial-black7mo ago
Yeah the thing is that go doesn't seem to register identifiers but only resources. I created a small work around for this, maybe you have a better idea:
import { useResource } from '@refinedev/core';
import { Link } from 'react-router-dom';

type LinkToResourceProps = {
resource: string;
};

export const LinkToResource = ({
resource: resourceProp,
children,
}: LinkToResourceProps & React.PropsWithChildren) => {
const { resource, resources } = useResource(resourceProp);
const toResource = resource || resources.find((r) => r.list);
const toLink = toResource?.list?.toString() || '';

return <Link to={toLink}>{children}</Link>;
};
import { useResource } from '@refinedev/core';
import { Link } from 'react-router-dom';

type LinkToResourceProps = {
resource: string;
};

export const LinkToResource = ({
resource: resourceProp,
children,
}: LinkToResourceProps & React.PropsWithChildren) => {
const { resource, resources } = useResource(resourceProp);
const toResource = resource || resources.find((r) => r.list);
const toLink = toResource?.list?.toString() || '';

return <Link to={toLink}>{children}</Link>;
};
This way I can use <LinkToResource resource={identifier}>{identifier}</LinkToResource> @batuhanw just pinging in case you didn't register my messages
rising-crimson
rising-crimson7mo ago
Hey @bastianwegge could you elaborate more on this one:
Yeah the thing is that go doesn't seem to register identifiers but only resources.
Do you mean, useGo doesn't find if you pass identifier?
xenial-black
xenial-black7mo ago
Yes that's exactly what I mean.
rising-crimson
rising-crimson7mo ago
Let me check that Are you using like this one?
const identifier = 'xxx'

useGo({ to: { resource: identifier, action: "list" }})
const identifier = 'xxx'

useGo({ to: { resource: identifier, action: "list" }})
xenial-black
xenial-black7mo ago
Yes (sorry for the late answer)
rising-crimson
rising-crimson7mo ago
Btw, actually there is a mistake in the documentation. We are not accepting resource object, resource’s type is string
xenial-black
xenial-black7mo ago
Yeah okay but isn't this supposed to work with an identifier as well?
rising-crimson
rising-crimson7mo ago
Yes. I've tested locally and it worked as expected. If you can provide a minimal reproducible example we can check it.