xenial-black
xenial-black13mo ago

How to retrieve a list of elements

Hello, I don't quite understand how refine works. I would like to retrieve the list of all my exercises (available on my api via GET: /exercises), the problem is that refine always adds end and start parameters to the query, I don't want that. What's more, I'd like to know, on a page that's neither List Show Edit or Create, a way of retrieving all this, what should I use? useOne? useMany? I don't know, I'm just starting out. Merci !
14 Replies
kapa.ai
kapa.ai13mo ago
Hi @realdragonma. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Hello! To fetch the list of all your exercises without the end and start parameters, you can create a custom data provider method. In this custom method, you can make a request to your API without those parameters. To fetch the data on a page that's neither List, Show, Edit, or Create, you can use the useList data hook. This hook is suitable for fetching multiple records from a resource. Here's an example of how to use the useList hook:
import { useList } from "@refinedev/core";

const { data } = useList({
resource: "exercises",
});
import { useList } from "@refinedev/core";

const { data } = useList({
resource: "exercises",
});
This code snippet will fetch all the exercises from your API. You can find more information about the useList hook in the useList documentation (https://refine.dev/docs/api-reference/core/hooks/data/useList/). I hope this helps you get started with refine! If you have any more questions, feel free to ask. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai13mo ago
<@214840332943097856> kapa.ai is still learning and improving, please let us how it did by reacting below
xenial-black
xenial-black13mo ago
It works fine, but why does the request always add "?_end=10&_start=0&" at the end? I don't want that.
rival-black
rival-black13mo ago
Because your requests send via the dataProvider you defined. If you want to change the default behavior of the dataProvider, you can create a custom dataProvider and use it in your project or override the default dataProvider methods. You can find more information here: https://refine.dev/docs/tutorial/understanding-dataprovider/index/
xenial-black
xenial-black13mo ago
Thank you, it works! The only problem is with the types now: here's what I'm doing:
const {data: data} = useList({
resource: 'sessions',
})

const sessions: ISession[] = data?.data.sessions;
const {data: data} = useList({
resource: 'sessions',
})

const sessions: ISession[] = data?.data.sessions;
but I get an error on the data.data: "TS2339: Property 'sessions' does not exist on type 'BaseRecord[]'." Is it possible not to return this BaseRecord[], but an any? Here's my dataProvider :
// Get list
getList: async ({ resource }): Promise<any> => {
const url = `${apiUrl}/${resource}`;

try {
const { data, headers } = await axiosInstance.get(`${url}`);
const total = +headers["x-total-count"];
return {data: data, total};
} catch (e) {
return {
data: [],
total: 0,
};
}

},
// Get list
getList: async ({ resource }): Promise<any> => {
const url = `${apiUrl}/${resource}`;

try {
const { data, headers } = await axiosInstance.get(`${url}`);
const total = +headers["x-total-count"];
return {data: data, total};
} catch (e) {
return {
data: [],
total: 0,
};
}

},
rival-black
rival-black13mo ago
You can use generics of the useList like below:
const {data: data} = useList<ISession>({
resource: 'sessions',
})
const {data: data} = useList<ISession>({
resource: 'sessions',
})
xenial-black
xenial-black13mo ago
Thank you for your response, but I'm sorry, the error persists: TS2339: Property 'sessions' does not exist on type 'ISession[]'. data?.data is equal:
{
sessions: [{...}]
}
{
sessions: [{...}]
}
So this is why I want that .sessions My sessions is accessible via "data.data.sessions"
rival-black
rival-black13mo ago
Could you share your usage of useList hook?
xenial-black
xenial-black13mo ago
I have no usage yet, I just want to see how it works, but the idea is to selection a sessions :
export default function ListSessions(): ReactElement | null {

const {data: data} = useList<ISession>({
resource: 'sessions',
})



const sessions: ISession[] = data?.data.sessions;

console.log(sessions);

return (
<>
<Space wrap>
<Select options={sessions.map(session => ({text: session.nom, value: session.nom}))}/>
<Select/>
</Space>
</>
);
}
export default function ListSessions(): ReactElement | null {

const {data: data} = useList<ISession>({
resource: 'sessions',
})



const sessions: ISession[] = data?.data.sessions;

console.log(sessions);

return (
<>
<Space wrap>
<Select options={sessions.map(session => ({text: session.nom, value: session.nom}))}/>
<Select/>
</Space>
</>
);
}
I just need to correct this type error Here is the value of data :
xenial-black
xenial-black13mo ago
No description
rival-black
rival-black13mo ago
When you give a generic type, you don't need to define type again like below:
const sessions: ISession[] = data?.data.sessions;
const sessions: ISession[] = data?.data.sessions;
Because, data?.data.sessions already will have ISession[] type
xenial-black
xenial-black13mo ago
So is there any way to access directly data.data.sessions ? and not data ?
rival-black
rival-black13mo ago
You should customize your dataProvider according to your API response:
// Get list
getList: async ({ resource }): Promise<any> => {
const url = `${apiUrl}/${resource}`;

try {
const { data, headers } = await axiosInstance.get(`${url}`);
const total = +headers["x-total-count"];
return {data: data, total};
} catch (e) {
return {
data: [],
total: 0,
};
}

},
// Get list
getList: async ({ resource }): Promise<any> => {
const url = `${apiUrl}/${resource}`;

try {
const { data, headers } = await axiosInstance.get(`${url}`);
const total = +headers["x-total-count"];
return {data: data, total};
} catch (e) {
return {
data: [],
total: 0,
};
}

},
What you return here with data should be an array. Currently, you are returning an object. So, you can refactor it like below:
// Get list
getList: async ({ resource }): Promise<any> => {
const url = `${apiUrl}/${resource}`;

try {
const { data, headers } = await axiosInstance.get(`${url}`);
const total = +headers["x-total-count"];
return {data: data[resource], total};
} catch (e) {
return {
data: [],
total: 0,
};
}

},
// Get list
getList: async ({ resource }): Promise<any> => {
const url = `${apiUrl}/${resource}`;

try {
const { data, headers } = await axiosInstance.get(`${url}`);
const total = +headers["x-total-count"];
return {data: data[resource], total};
} catch (e) {
return {
data: [],
total: 0,
};
}

},
xenial-black
xenial-black13mo ago
Thanks !