pbeshai / serialize-query-params Goto Github PK
View Code? Open in Web Editor NEWA javascript library for simplifying encoding and decoding URL query parameters
A javascript library for simplifying encoding and decoding URL query parameters
See pbeshai/use-query-params#148 for details
Using the following setup, I get a typescript error saying my enum param can still be null. Am I misunderstanding something, or should the types reflect that this value is never null?
const SortOrderEnumParam = createEnumParam(['asc', 'desc']);
const [filters, setFilters] = useQueryParams({
sortBy: withDefault(SortOrderEnumParam, 'asc'),
});
const sorted = sortFunctions[filters.sortBy](unsorted);
[tsserver 2538] [E] Type 'null' cannot be used as an index type
[tsserver 2538] [E] Type 'undefined' cannot be used as an index type.
Revealing the types of other query params that use withDefault
show that they are never null or undefined, but the ones using my custom enum param may still be both, according to typescript.
To please the typechecker, I have to add the default a second time, for instance like this:
const sorted = sortFunctions[filters.sortBy ?? 'asc'](unsorted);
Hi there! I absolutely love your work here and in use-query-params
.
When using DelimitedArrayParam
, since _
is used as the delimiter, strings containing underscores are deserialized incorrectly (they are split into multiple strings after serialization then deserialization). To avoid this, some kind of escaping is necessary.
The same applies for strings with -
or _
characters when using ObjectParam
s.
When using updateLocation
or updateInLocation
, the href
property of the returned object is not updated with the new query params. This would otherwise be a good way to pass the new location into functions like history.pushState
that require a URL string, but currently you have to stitch together (at least) the pathname
and search
on your own.
var loc = {
host: "localhost:4000",
hostname: "localhost",
href: "http://localhost:4000/test?param=0",
origin: "http://localhost:4000",
pathname: "/test",
port: "4000",
protocol: "http:",
search: "?param=0"
};
var newLoc = updateInLocation({ param: "1" }, loc);
// => { ..., search: "?param=1", href: "http://localhost:4000/test?param=0" }
Update serializers to allow null and empty string values:
null
maps to ?foo
""
maps to ?foo=
undefined
maps to ?
(not present/remove)Api has not changed too much, should be trivial :)
I suppose the solution is just to check if require
is is defined before calling the function and bail out otherwise since it's just a handy dev check.
Before there have been possibility to remove arguments by passing them with empty value
https://github.com/pbeshai/serialize-query-params/blob/v0.1.4/src/updateLocation.ts#L64
for now nully check is removed.
https://github.com/pbeshai/serialize-query-params/blob/master/src/updateLocation.ts#L84
Could you please clarify, how to migrate such behavior (remove parameters instead of updating them) with your library?
Hey there! It seems like query-string just published a major version (7.0.0) last week, I was just wondering whether it was possible for you to update the peer dependency on it to 7.0.0?
https://www.npmjs.com/package/query-string?activeTab=versions
Why do empty array is returned empty string in encodeDelimitedArray? Wouldn't it make more sense for it to return undefined so /?foo=
is removed from the url?
Assuming,
foo
is CommaArrayParam (as defined in the example).
When I remove all items from the array, it leaves an empty string, so /?foo=
will be left in the URL.
Just a curious question. Keep up the good work. 😄
I am currently using custom param like this -
https://gist.github.com/akshitkrnagpal/2baf5b7d41751bfcdc98f2d380bec3b0
Trying to run the example code from the readme, and receive error that stringify is not exported.
import {
stringify,
encodeQueryParams,
NumberParam,
DelimitedArrayParam,
} from 'serialize-query-params';
// encode each parameter according to the configuration
const encodedQuery = encodeQueryParams(
{ foo: NumberParam, bar: DelimitedArrayParam },
{ foo: 123, bar: ['a', 'b'] }
);
// produces: { foo: '123', bar: 'a_b' }
const link = `/?${stringify(encodedQuery)}`;
Assume it should just be:
import {
encodeQueryParams,
NumberParam,
DelimitedArrayParam,
} from 'serialize-query-params';
import { stringify } from 'query-string';
// encode each parameter according to the configuration
const encodedQuery = encodeQueryParams(
{ foo: NumberParam, bar: DelimitedArrayParam },
{ foo: 123, bar: ['a', 'b'] }
);
// produces: { foo: '123', bar: 'a_b' }
const link = `/?${stringify(encodedQuery)}`;
Skipped query-string 7 version check function in the in "Development" mode in the index.ts file, the regular expression in it only checks to version 6.
const validQueryStringInstalled =
/^5.1.[1-9][0-9]*/.test(queryStringVersion) ||
/^6\./.test(queryStringVersion);
if (!validQueryStringInstalled) {
throw new Error(
`serialize-query-params requires query-string ^5.1.1 || ^6, ` +
`but ${queryStringVersion} is installed. Note: you may also ` +
`see this message if you're using use-query-params.`
);
}
}
Error:
/home/bipboy/project/test/common/temp/node_modules/.pnpm/[email protected][email protected]/node_modules/serialize-query-params/lib/index.js:63
throw new Error("serialize-query-params requires query-string ^5.1.1 || ^6, " +
^
Error: serialize-query-params requires query-string ^5.1.1 || ^6, but 7.0.0 is installed. Note: you may also see this message if you're using use-query-params.
at Object.<anonymous> (/home/bipboy/project/test/common/temp/node_modules/.pnpm/[email protected][email protected]/node_modules/serialize-query-params/lib/index.js:63:15)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (/home/bipboy/project/test/common/temp/node_modules/.pnpm/[email protected]_fbb1568849e39ef343f2f6b5a928879a/node_modules/use-query-params/lib/index.js:6:10)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
When using updateLocation
or updateInLocation
, the returned object inherits the methods of Location
, but calling them doesn't work because the object is not actually a Location
.
In Firefox, I get this error:
var newLoc = updateLocation({ foo: "bar" }, location);
location.toString();
// TypeError: 'toString' called on an object that does not implement interface Location.
It's probably fine if the returned object is not a real Location
, but in that case I think it should avoid inheriting the methods. This ensures that if someone tries to call them, it fails to compile (if using TypeScript anyway) instead of failing at runtime.
Alternatively, the returned object could be a real Location
, but I'm not sure if that's possible or how much refactoring it would require.
Maybe in decodingQueryParams
you should iterate over the paramConfigMap
and not the encodedQuery
?
My use case is to keep all filters/search options of a screen in query string
I'd like to declare complex encoding/decoding params to make sure all filters keys are parsed properly
example of date range param
import moment, { Moment } from 'moment';
import { QueryParamConfig, encodeObject, decodeObject } from 'use-query-params';
type DateRange = {
begin: Moment;
end: Moment;
};
export const DateRangeParam: QueryParamConfig<DateRange> = {
encode(dateRangeObj: { begin: Moment; end: Moment }): string | undefined {
if (dateRangeObj === null) {
return undefined;
}
if (!dateRangeObj.begin) {
return encodeObject({
end: dateRangeObj.end.toISOString(),
});
}
if (!dateRangeObj.end) {
return encodeObject({
begin: dateRangeObj.begin.toISOString(),
});
}
return encodeObject({
begin: dateRangeObj.begin.toISOString(),
end: dateRangeObj.end.toISOString(),
});
},
decode(input: string | string[] | null | undefined): Moment | undefined {
if (input == null || !input.length) {
return undefined;
}
const dateRangeObj = decodeObject(input);
return {
begin: dateRangeObj.begin ? moment(dateRangeObj.begin) : null,
end: dateRangeObj.end ? moment(dateRangeObj.end) : null,
};
},
};
example: date=begin-2020-01-01T03%3A00%3A00.000Z_end-2020-01-31T03%3A00%3A00.000Z
I'd like to easily to something like this:
ObjectParams<{begin: MomentParam, end: MomentParam>
similar to yup validation schema (https://github.com/jquense/yup)
e.g. using Date().toISOString()
as requested in pbeshai/react-url-query#39
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.