Cleanup api search

This commit is contained in:
Nicolas Mowen 2024-09-10 10:12:07 -06:00
parent c59aae718d
commit 3b813d3256

View File

@ -1,6 +1,26 @@
import { FilterType } from "@/types/filter"; import { FilterType } from "@/types/filter";
import { useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom"; import { useSearchParams } from "react-router-dom";
function getStringifiedArgs(filter: FilterType) {
const search: { [key: string]: string } = {};
Object.entries(filter).forEach(([key, value]) => {
if (Array.isArray(value)) {
if (value.length == 0) {
// empty array means all so ignore
} else {
search[key] = value.join(",");
}
} else {
if (value != undefined) {
search[key] = `${value}`;
}
}
});
return search;
}
type useApiFilterReturn<F extends FilterType> = [ type useApiFilterReturn<F extends FilterType> = [
filter: F | undefined, filter: F | undefined,
@ -21,23 +41,7 @@ export default function useApiFilter<
return {}; return {};
} }
const search: { [key: string]: string } = {}; return getStringifiedArgs(filter);
Object.entries(filter).forEach(([key, value]) => {
if (Array.isArray(value)) {
if (value.length == 0) {
// empty array means all so ignore
} else {
search[key] = value.join(",");
}
} else {
if (value != undefined) {
search[key] = `${value}`;
}
}
});
return search;
}, [filter]); }, [filter]);
return [filter, setFilter, searchParams]; return [filter, setFilter, searchParams];
@ -46,51 +50,21 @@ export default function useApiFilter<
export function useApiFilterArgs< export function useApiFilterArgs<
F extends FilterType, F extends FilterType,
>(): useApiFilterReturn<F> { >(): useApiFilterReturn<F> {
const location = useLocation(); const [rawParams, setRawParams] = useSearchParams();
const navigate = useNavigate();
const setFilter = useCallback( const setFilter = useCallback(
(filter: F) => { (newFilter: F) => setRawParams(getStringifiedArgs(newFilter)),
let search = ""; [setRawParams],
Object.entries(filter).forEach(([key, value]) => {
let char = "";
if (search.length == 0) {
char = "?";
} else {
char = "&";
}
if (Array.isArray(value)) {
if (value.length == 0) {
// empty array means all so ignore
} else {
search += `${char}${key}=${value.join(",")}`;
}
} else {
if (value != undefined) {
search += `${char}${key}=${value}`;
}
}
});
navigate(`${location.pathname}${search}`, { ...location.state });
},
[location, navigate],
); );
const filter = useMemo<F>(() => { const filter = useMemo<F>(() => {
const search = location?.search?.substring(1); if (rawParams.size == 0) {
if (search == undefined || search.length == 0) {
return {} as F; return {} as F;
} }
const filter: { [key: string]: unknown } = {}; const filter: { [key: string]: unknown } = {};
search.split("&").forEach((full) => { rawParams.forEach((value, key) => {
const [key, value] = full.split("=");
if (isNaN(parseFloat(value))) { if (isNaN(parseFloat(value))) {
filter[key] = value.includes(",") ? value.split(",") : [value]; filter[key] = value.includes(",") ? value.split(",") : [value];
} else { } else {
@ -101,30 +75,14 @@ export function useApiFilterArgs<
}); });
return filter as F; return filter as F;
}, [location?.search]); }, [rawParams]);
const searchParams = useMemo(() => { const searchParams = useMemo(() => {
if (filter == undefined || Object.keys(filter).length == 0) { if (filter == undefined || Object.keys(filter).length == 0) {
return {}; return {};
} }
const search: { [key: string]: string } = {}; return getStringifiedArgs(filter);
Object.entries(filter).forEach(([key, value]) => {
if (Array.isArray(value)) {
if (value.length == 0) {
// empty array means all so ignore
} else {
search[key] = value.join(",");
}
} else {
if (value != undefined) {
search[key] = `${value}`;
}
}
});
return search;
}, [filter]); }, [filter]);
return [filter, setFilter, searchParams]; return [filter, setFilter, searchParams];