jolly-crimson
jolly-crimson9mo ago

searchParams

hi, I m struggling to mimic refine's filters searchParams management. So i tried to convert my filters to a param like refine struture. But when i append it to the searchParams, i always get encoded, how refine handle this? const updateFilterParams = (field: string, value: string): void => { const filters = generateFilterParams([ { field, operator: "eq", value, }, ]); setSearchParams((prev: URLSearchParams) => { const newSearchParams = new URLSearchParams(prev.toString()); const filterSearchParams = new URLSearchParams(filters); filterSearchParams.forEach((value, key) => { newSearchParams.append(key, value); }); return newSearchParams; }); }; export const generateFilterParams = (filters?: CrudFilters) => { const params = new URLSearchParams(); if (filters) { filters.forEach((filter, index) => { if ("field" in filter) { const { field, operator, value } = filter; params.append(filters[${index}][field], field); params.append(filters[${index}][operator], operator); if (Array.isArray(value)) { value.forEach((value, valueIndex) => { params.append(filters[${index}][value][${valueIndex}], value); }); } else { params.append(filters[${index}][value], value); } } }); } return params; };
8 Replies
kapa.ai
kapa.ai9mo ago
Hi @tuanna_. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Refine provides a syncWithLocation property that allows you to edit query parameters manually and share the current page, items count per page, sort, and filter parameters easily with others. This property can be used to sync the filtering state with the URL. Here's an example of how you can use the syncWithLocation property:
function App() {
return (
<ThemeProvider theme={LightTheme}>
<CssBaseline />
<GlobalStyles styles={{ html: { WebkitFontSmoothing: "auto" } }} />
<RefineSnackbarProvider>
<Refine
...
options={{
mutationMode: "undoable",
syncWithLocation: true
}}
/>
</RefineSnackbarProvider>
</ThemeProvider>
);
}

export default App;
function App() {
return (
<ThemeProvider theme={LightTheme}>
<CssBaseline />
<GlobalStyles styles={{ html: { WebkitFontSmoothing: "auto" } }} />
<RefineSnackbarProvider>
<Refine
...
options={{
mutationMode: "undoable",
syncWithLocation: true
}}
/>
</RefineSnackbarProvider>
</ThemeProvider>
);
}

export default App;
With syncWithLocation enabled, you can get the current information from the URL as query parameters. You can either use this link to share with others or define filter, pagination, and sorting parameters manually by changing the URL parameters. However, please note that if syncWithLocation is enabled, on page refresh filter values will be of type string since they will be parsed from the URL. This might produce some incompatibility if data for the filter input comes from an API and it's not of type string source (https://refine.dev/docs/api-reference/antd/components/filter-dropdown). In your case, you are trying to append the filters to the URLSearchParams. However, URLSearchParams will encode the parameters. If you want to avoid this, you might need to handle the URL parameters manually. For more specific information on handling filters with refine, you can refer to the refine documentation (https://refine.dev/docs/advanced-tutorials/data-provider/handling-filters/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@353701348463738885> kapa.ai is still learning and improving, please let us know how it did by reacting below
jolly-crimson
jolly-crimson9mo ago
@kapa.ai syncWithLocation seem to work with only useTable and useSimpleList, im using useList instead so im trying to manually do that
kapa.ai
kapa.ai9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- If you're using useList and want to manually handle URL parameters to mimic the syncWithLocation functionality, you can do so by using the history and location objects from the react-router-dom library. Here's a simplified example of how you might handle this:
import { useHistory, useLocation } from 'react-router-dom';

// ...

const history = useHistory();
const location = useLocation();

const updateFilterParams = (field: string, value: string): void => {
const filters = generateFilterParams([
{
field,
operator: "eq",
value,
},
]);

// Create a new URLSearchParams instance with the current search string
const searchParams = new URLSearchParams(location.search);

// Update the search params with the new filters
const filterSearchParams = new URLSearchParams(filters);
filterSearchParams.forEach((value, key) => {
searchParams.set(key, value);
});

// Update the URL with the new search params
history.push({ pathname: location.pathname, search: searchParams.toString() });
};

// ...
import { useHistory, useLocation } from 'react-router-dom';

// ...

const history = useHistory();
const location = useLocation();

const updateFilterParams = (field: string, value: string): void => {
const filters = generateFilterParams([
{
field,
operator: "eq",
value,
},
]);

// Create a new URLSearchParams instance with the current search string
const searchParams = new URLSearchParams(location.search);

// Update the search params with the new filters
const filterSearchParams = new URLSearchParams(filters);
filterSearchParams.forEach((value, key) => {
searchParams.set(key, value);
});

// Update the URL with the new search params
history.push({ pathname: location.pathname, search: searchParams.toString() });
};

// ...
In this example, useHistory and useLocation are hooks from react-router-dom that give you access to the history and location objects, respectively. You can use these objects to read and update the current URL. Please note that this is a simplified example and might not cover all edge cases. You might need to adjust the code according to your actual data structure and requirements. For more information on handling filters with refine, you can refer to the refine documentation (https://refine.dev/docs/advanced-tutorials/data-provider/handling-filters/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@353701348463738885> kapa.ai is still learning and improving, please let us know how it did by reacting below
jolly-crimson
jolly-crimson9mo ago
@kapa.ai how refine's syncwithlocation works
kapa.ai
kapa.ai9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Refine's syncWithLocation feature allows the state of your data grid or table (such as sort order, filters, and pagination) to be automatically encoded in the query parameters of the URL. When the URL changes, the state of your data grid or table is automatically updated to match. This makes it easy to share table states across different routes or pages and allows users to bookmark or share links to specific table views. The syncWithLocation feature is set to false by default. You can enable it by setting syncWithLocation: true in the options of your Refine, useDataGrid, useTable, or useSimpleList component. Here's an example of how you can enable it in the Refine component:
function App() {
return (
<Refine
// ...
options={{ syncWithLocation: true }}
>
// ...
</Refine>
);
}
function App() {
return (
<Refine
// ...
options={{ syncWithLocation: true }}
>
// ...
</Refine>
);
}
When syncWithLocation is enabled, the current information from the URL can be obtained as query parameters. You can use this link to share with others or define filter, pagination, and sorting parameters manually by changing the URL parameters. However, please note that if syncWithLocation is enabled, on page refresh filter values will be of type string since they will be parsed from the URL. This might produce some incompatibility if data for the filter input comes from an API and it's not of type string. For more information, you can refer to the following documentation pages: - useDataGrid (https://refine.dev/docs/api-reference/mui/hooks/useDataGrid/#syncwithlocation) - useTable (https://refine.dev/docs/api-reference/antd/hooks/table/useTable/#syncwithlocation) - useSimpleList (https://refine.dev/docs/api-reference/antd/hooks/list/useSimpleList/#syncwithlocation) - Refine (https://refine.dev/docs/api-reference/core/components/refine-config/#syncwithlocation) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@353701348463738885> kapa.ai is still learning and improving, please let us know how it did by reacting below