I need to convert a query string into an object, but with the respective data types. Let me explain it better: I use a table from an external service that generates filters when I add them. I need to put these filters into a query string and then read them back. When I read them back, I need each type to return to its initial state. For example, if before putting the query in the query string I have { foo: 10 }
, I need it to have the same thing when reading it back and not { foo: "10" }
. However, we know that the query string is, in fact, a string, and when I convert it back, the values of the JSON attributes are still strings. I’m not asking you to create a method for me that does this, but I would like to know if you know of a simpler way, such as some utility.
I started writing this method:
const parseStringToJson = (str: string | null | undefined): object => {
// str is skip=0&take=10
const parsedJSON: any = QueryString.parse(str || {});
// parsedJSON is { skip: "0", take: "10"}
const convertDataType = (data: object | null): void => {
Object.entries(data || {}).forEach(([key, value]) => {
let isNumber = (typeof value === 'number' || (typeof value === 'string' && !isNaN(parseFloat(value))));
let isBoolean = value === 'true' || value === 'false';
//value is number
if (isNumber) {
return (parsedJSON[key] = Number(value));
}
//value is boolean
if (isBoolean) {
return (parsedJSON[key] = value === 'true');
}
//value is string
if (typeof value === 'string' && !isNumber) {
return (parsedJSON[key] = value);
}
});
};
convertDataType(parsedJSON);
// parsedJSON is { skip: 0, take: 10}
return parsedJSON;
};
Where QueryString is imported from qs
This works only with one level objects, but I need to do it deep inside. Also Manage arrays.
So before I starting doing that, Do you have a better idea to do so?
2
Answers
Your
parsedJSON
is not JSON (it’s already a plain object) and so what you’re asking seems to be a poorly phrased "how do I automatically convert strings to other datatypes if that’s what they are".Ironically, one of the answers here (if you don’t want to use a schema library, which you probably should) is to create an actual JSON string representation of your object, using a replacer function that converts values on the fly (because JSON.stringify is a tree-walker) and then parsing the result back from JSON to plain object:
Is this a good solution? No. Use a model/schema solution that can ingest string data and automatically convert it to the data type it should be. With model validation, so that if you’re trying to create an incomplete or incompatible model instance, you can catch that and do whatever you need to do on input failure.
Is it a fun solution? Absolutely. Tree-walking an object using
JSON.stringify
is one of JS’s hidden bonus features.