parsing a TypeScript query

Is there a simpler way to convert a query string into an object while preserving the respective data types? Let me provide some context: I utilize a table from an external service that generates filters as I add them. The challenge arises when I need to encode these filters into a query string and then decode them back into their original formats. For instance, if my initial filter is { foo: 10 }, I want it to remain unchanged when decoded, rather than being transformed into { foo: "10" }. However, since query strings are essentially strings, the values of JSON attributes end up as strings when decoded. Although I am not seeking a method implementation, I would appreciate any insights or suggestions on simplifying this process, perhaps through the use of utilities.

I have initiated the following method:

const parseStringToJson = (str: string | null | undefined): object => {
  // str example: skip=0&take=10
  const parsedJSON: any = QueryString.parse(str || {});
  // parsedJSON example: { 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 example: { skip: 0, take: 10}
  return parsedJSON;
};

QueryString module is imported from qs

This methodology currently handles only shallow objects, leaving the need for deep nested structures and arrays unaddressed. Before delving further into this solution, do you have any alternative approaches in mind?

Answer №1

Your parsedJSON is not actually JSON, but rather a plain object. It appears that you are inquiring about how to automatically convert any string values within this object to other data types, regardless of their depth within the structure.

An interesting approach suggested here (although it is recommended to use a schema library) involves creating a true JSON string representation of the object using a replacer function that can dynamically convert values as needed, and then parsing the modified JSON back into a plain object:

const someData = {
  cake: "yum",
  ingredients: {
    eggs: "3",
    oil: "false",
  },
  timings: ["short", "30", "short"]
};

function convert(key, value) {
  const type = typeof value;
  if (type === `string`) {
    const trimmed = value.trim();
    const num = parseFloat(trimmed);
    if (trimmed == num) return num;
    const lc = trimmed.toLowerCase();
    if (lc === `true`) return true;
    if (lc === `false`) return false;
  }
  if (type === `function`) return;
  return value;
}

console.log(
  JSON.parse(
    JSON.stringify(someData, convert)
  )
);

While this solution may not be optimal for production use, it certainly offers an intriguing way to manipulate objects in JavaScript by leveraging the abilities of JSON.stringify.

For a more robust and reliable solution, consider utilizing a model/schema system that can handle data conversion and validation seamlessly. This ensures consistency and accuracy when dealing with different data types within your application.

Although unconventional, exploring unconventional methods like object manipulation through JSON.stringify can be both educational and entertaining in the world of JavaScript programming.

Answer №2

Exploring the process of distinguishing numbers within strings.

let exampleArr = ["one", "1", 0, 03, "02"];

exampleArr.forEach(function(element){
if(isNaN(element)){
   console.log("The value '" + element + "' is not a valid number");
} else {

  console.log("Value '" + element + "' converts to " + Number(element));
}
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transferring JavaScript to PHP

I have a challenge where I need to pass a string stored in a variable to a MySQL table using PHP. Currently, my workaround involves using a hidden <input>. I assign the variable value to it and submit it through a form. It works, but it's not e ...

Is there a way to ensure that the await subscribe block finishes before moving on to the next line of code?

My goal is to utilize the Google Maps API for retrieving coordinates based on an address. In my understanding, using await with the subscribe line should ensure that the code block completes before moving on to the subsequent lines. async getCoordinates ...

Unit testing in Angular 2+ involves testing a directive that has been provided with an injected window object

Currently, I am faced with the challenge of creating a test for a directive that requires a window object to be passed into its constructor. This is the code snippet for the directive: import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit ...

What is the process for retrieving information from a retail outlet?

How can I retrieve data from the Vuex store using Vue.js? Below is my code: Vue.use(Vuex); export default new Vuex.Store({ modules: { data } }) data.js import axios from 'axios'; const state = { data: '' }; cons ...

Checkbox ensemble computes total score

I am currently working on a project that involves multiple checkbox groups, with each group containing 3 checkboxes labeled as (1, X, 2). My goal is to assign a value of 100% to each group, distributed evenly among the checkboxes within it. The distributio ...

Using regular expressions in JavaScript, eliminate all characters preceding a specified final character

I am attempting to eliminate all text that precedes the last character in a Regex pattern. For example: rom.com/run/login.php Would turn into: login.php Can someone guide me on how to achieve this using JavaScript? I have limited experience with regul ...

The attribute 'getValue' is not a valid property for the data type 'Subject<boolean>'

Currently, I am working with Angular2 and have a BehaviorSubject. isOpen$: Subject<boolean> = new BehaviorSubject<boolean>(true); When I try to retrieve the latest value using: isOpen$.getValue() It functions correctly, however, there is a ...

What is the best way to dynamically assign a value to an anchor tag upon each click using jQuery?

How can I pass a value to an anchor tag on every click using jQuery? I am encountering an issue with my current code where the value is not being retrieved when I click the button. //HTML snippet <button id="a-selectNm" data-a_name="<?php echo $row[ ...

Countdown alert using JavaScript

Currently in my frontend code, I am utilizing angularjs as the javascript framework. In a specific section of my code, I need to display an error message followed by a warning message in this format: If a user inputs an incorrect month, then the following ...

Issue with Angular: Unable to update model before modal closure on submit

I have a search form that is displayed within a modal window created using Angular UI Bootstrap. The input fields in the form update the ng-model when submitted. <script type="text/ng-template" id="mobileSearchPanel"> <form> ...

Creating a process to produce a random number and send it directly to an automated email

I'm currently utilizing a form builder from jqueryform.com to construct a registration form. My goal is to have each registered user assigned with a unique account number, which will be a randomly generated 6-digit number. Additionally, I want the pro ...

Exploring objects as strings to retrieve data with Javascript

In a scenario where I receive an object of varying length that I do not control, I am required to extract specific data from it. The response I receive is in the form of a formatted string: { "questionId": 18196101, "externalQuestionId": "bcc38f7 ...

Getting a "function is not defined" error in Angular 6 while using it within a nested function

I'm facing an issue related to typescript, where the following code is causing trouble: private loadTeams = function(){ let token = sessionStorage.getItem('token'); if(token !== undefined && token !== null && token ...

Bot on Discord using Discord.Js that generates unique invites for users

I'm trying to find a way to generate an invite link for users to keep track of invites. The code I have currently is creating the invite for the Bot instead. const channel = client.channels.cache.find(channel => channel.id === config.server.channel ...

Can we set a specific length for an array passed in as a prop?

Can we use Typescript to specify the exact length of an array coming from props? Consider the following array of objects: const sampleArray = [ { key: '1', label: 'Label 1', value: 9 }, { key: '2', label: 'Label 2&ap ...

Angular2 - leveraging root-relative imports

Having trouble with imports in angular2/typescript? Want to use paths relative to the project root like 'app/components/calendar', but currently stuck using something like this: //app/views/order/order-view.ts import {Calendar} from '../../ ...

Discover an Effective Approach for Transmitting Form-Data as a JSON Object

Hey there! I'm encountering a bit of an issue with sending some data as a JSON object. The problem arises when trying to send images using FormData. It seems like I need to convert my form data into a single JSON object. Can anyone assist me with this ...

Oops! The provided value for the argument "value" is not a valid query constraint. Firestore does not allow the use of "undefined" as a value

I encountered an error while exporting modules from file A and importing them into file B. When running file B, the error related to Firebase Cloud Firestore is displayed. const getMailEvents = (startTime, endTime) => { serverRef = db.collection("Ma ...

What causes Bootstrap to malfunction when the route contains double slashes?

When using /something, everything works fine, but when switching to /something/somethingelse, Bootstrap fails to function. It seems that the number of "/" characters in the route is causing this issue, rather than the content inside the .ejs file. Here is ...

Accessing a model's field within an Ember.js each loop

Here is the code for a route that I am working on: Calendar.DateIndexRoute = Ember.Route.extend({ model: function(data) { return {arr:getCalendar(data), activeYear: data.year, activeMonthNumber: data.month, activeDay: data.da ...