JavaScript - Imported function yields varied outcome from module

I have a utility function in my codebase that helps parse URL query parameters, and it is located within my `utils` package. Here is the code snippet for the function:

export function urlQueryParamParser(params: URLSearchParams) {
  const output:any = {};
  const searchParams = new URLSearchParams(params);

  new Set([...searchParams.keys()])
    .forEach(key => {
      output[key] = searchParams.getAll(key).length > 1 ?
        searchParams.getAll(key) :
        searchParams.get(key)
    });

  return output;
}

To make this function accessible throughout my project, I export it in the main index file along with other modules like so:

export * from './utils/urlQueryParamParser'

When I import and use this function in one of my modules using the statement

import { urlQueryParamParser } from '@mypackages/utils'
, I notice that the result returned is not as expected:

{
    "[object Iterator]": null
}

However, if I directly copy this function into the module where I am calling it, the return result is correct and looks something like this:

{
    "filter": "all",
    "query": "",
    "range": "today",
    "from": "2022-11-22",
    "to": "2022-12-22",
    "claims": [
        "damaged",
        "missing-article"
    ]
}

I am curious about why there is a difference in the results when importing the function versus using it directly within the same file. The TypeScript version used in the module where I import the function is:

"typescript": "^4.7.2",

And the `tsconfig.json` configuration for that module is as follows:

{
  "compilerOptions": {
    // Configuration options here...
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"],
  "files": ["custom.d.ts"]
}

On the other hand, the TypeScript version specified in the package module is:

"typescript": "^4.7.4"

And its corresponding `tsconfig.json` content is provided below:

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    // Configuration options here...
  },
  "exclude": ["**/node_modules", "**/.*/", "dist", "build"],
  "include": ["src/**/*.ts", "src/**/*.tsx"]
}

Answer №1

Expanding on my previous comment.

My suspicion is that the issue stems from not properly spreading the keys in your array within the file located in the package. Instead of adding each key individually, it seems like you inserted the iterator object as the only element in the array.

It appears that you may have mistakenly used new Set([searchParams.keys()]) instead of

new Set([...searchParams.keys()])
in either your current or past version, leading to a compilation error (potentially due to incorrect caching).

Curiously, TypeScript did not seem to issue a warning when this mistake was made. To avoid similar oversights, I found it necessary to include // @ts-nocheck in my code while trying to replicate the problem.


The challenge lies in reproducing the issue given the limited details provided. For future reference, it would be beneficial to create a project showcasing the problem using CodeSandbox.

Answer №2

If you are working with TypeScript versions older than 2.3.1, you may encounter issues with URLSearchParams not being recognized as an iterable object. This can result in unexpected behavior when trying to spread it, as JavaScript may return "[object Iterator]" instead of raising an error.

It is important to note that the parameter params should be a string or URL['search'], depending on the context of your function. Whether you pass the parameters as a string or the output of another URLSearchParams instance, the outcome will be the same.

The inconsistency in functionality between different cases could be due to mismatched versions in your tsconfig.json and package.json files. It is also possible that packages like @mypackages are using a different version of TypeScript compared to the project utilizing the function. Providing detailed information about your versions and environment would aid in resolving any issues.

Answer №3

I'm taking a shot in the dark here, but have you tried replacing the spread operator with Array.from to see if it works?

function urlQueryParamParser(params: URLSearchParams) {
  const output:any = {};
  const searchParams = new URLSearchParams(params);

  new Set(Array.from(searchParams.keys()))
    .forEach(key => {
      output[key] = searchParams.getAll(key).length > 1 ?
        searchParams.getAll(key) :
        searchParams.get(key)
    });

  return output;
}

Answer №4

Ensure that in the tsconfig.json file of your module, you have correctly set the noEmit flag to true. This is crucial for successful compilation.

Answer №5

One workaround is to utilize the relative path for importing.

import { urlQueryParamParser } from '../mypackages/utils'; // instead of '@packages/utils'

You can also make modifications to the utils/index.js file as follows:

import { urlQueryParamParser } from "./urlQueryParamParser";

export default {
  urlQueryParamParser
};

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

Accordion featuring collapsible sections

Looking to build an accordion box using Javascript and CSS. The expanded section should have a clickable link that allows it to expand even further without any need for a vertical scroll bar. Any ideas on how this can be achieved? Thank you ...

Vue + TypeScript prop type issue: "'Foo' is intended as a type, but is being treated as a value in this context."

As a newcomer to TypeScript and the Vue Composition API, I encountered an error that left me puzzled: I have a component that requires an api variable as a prop, which should be of type AxiosInstance: export default defineComponent({ props: { api: A ...

How to extract only the truthy keys from an object using Angular.js

I am looking to retrieve only the keys with a true value in the data object and display them in the console with the specified format: Object { Agent=true, Analytics / Business Intelligence=true, Architecture / Interior Design=false } The catego ...

The code breaks when the lodash version is updated to 4.17.4

After updating lodash to version 4.17.4, I encountered an error in Typescript that says: TypeError: _.uniqBy is not a function Uncaught TypeError: _.split is not a function The code snippet in question is as follows: import * as _ from 'lodash&apo ...

Is it possible for me to make the default export anonymous?

Why bother naming the export if you already have a file with the default export name? This seems redundant and goes against the DRY principle. While there is a rule that discourages anonymous default exports, how can we enforce an error when someone does ...

Generating HTML tables with charts using FireFox

I am encountering an issue: My table contains charts and tables that are displayed correctly in browsers. However, when I attempt to print it (as a PDF) in Mozilla Firefox, the third speedometer gets cut off, showing only 2.5 speedometers. Using the "s ...

Tips for saving data obtained from an ajax call

My jquery ajax function has a callback that creates an array from retrieved json data. Here's an example: success: function (response) { callback(response); }, The callback function, in this case createQuestionsArray(), populates ...

Obtaining a string from a regular expression does not function as anticipated

Currently, I am in the midst of a project that requires me to identify specific HTML tags and replace them with others. To accomplish this task, I am utilizing JavaScript, and the code snippet looks like this: // html to update html = '<div cla ...

Using NextJs to create a permanent redirect from the www version of a site to the non

I have developed a website using Nextjs (version 12.1.4). To enhance the SEO of my site, I want to create a permanent redirect from the www version to the non-www version. Typically, this can be achieved easily using nginx or an .htaccess file with apache. ...

Error: Custom Service is behaving unpredictably

My latest project involves creating a customized service. While the service function is returning data as expected, I encounter an issue when calling it in the controller - it returns 'undefined'. Service: var toDoListServices = angular.module( ...

Learn how to create a logarithmic scale graph using CanvasJS by fetching data from an AJAX call

window.onload = function() { var dataPoints = []; // fetching the json data from api via AJAX call. var X = []; var Y = []; var data = []; function loadJSON(callback) { var xobj = new XMLHttpRequest(); xobj.overrideMimeType("applicatio ...

Utilizing LoopBack Storage Service: Leveraging upload/download functions within JavaScript code

Is there a straightforward way to upload and download files using the storageService.upload and storageService.download functions in my JavaScript/Loopback code? I'm trying to achieve something like this: app.post("/sendFile", (req, res) => client ...

Building a Dynamic Web App with PHP and Vue.js

I developed an API using PHP and you can access it through this link: However, I encountered an issue when trying to display the data on the front-end of my Vue.js (Home.vue) file using axios. Below is the code I used: <ul class="ta-track-list" v-if= ...

Inserting a variable into a JSON string

Within my code, I have a basic variable containing strings that are converted into a JSON object. My goal is to create an input field where a person's name can be entered and added to the text. The current setup looks like this var text = '{"st ...

The res.download() function in Express is failing to deliver the accurate URL to the client

When trying to utilize the res.download() method for downloading specific files from a server, there is an issue where triggering the res.download does not redirect the client to the correct URL. The files intended for download are located in a directory s ...

Uploading my application on multiple servers after making changes using AngularJS and PHP

Currently, I am working on an angular-php web application that is live online for multiple users, each on their own subdomain. These subdomains include: sub1.mydomain.com sub2.mydomain.com sub3.mydomain.com sub4.mydomain.com sub5.mydomain.com Issue: An ...

Utilizing Next 13 for flexible MDX imports

Recently completed the Next13 + MDX Tutorial, however, I am still unclear on how to dynamically load my mdx files. My mdx files are not hosted on a remote server, so I do not require next-mdx-remote. Nonetheless, I am in need of a method to load different ...

Determine the maximum array size in Javascript

Having trouble setting a limit in my custom lightbox for a gallery <script> var imagenumber = 0; function btnleft(){ load = imagenumber-=1; document.getElementById('lightboxcontent').innerHTML=imagelist[load]; ...

Leverage the Node Short ID library in conjunction with Angular 6 using TypeScript

I attempted to utilize the node module within an Angular 6 typescript environment. Step one: npm i shortid Within my TypeScript class: import { shortid } from 'shortid'; let Uid = shortid.generate(); However, I encountered an error stating ...

The $scope.$watch function is not triggering events within a controller of a ui.bootstrap.modal

Currently, I am utilizing UI bootstrap for Angular and have successfully integrated the ui.bootstrap.modal component into my project. Everything seems to be working smoothly except for one issue I am encountering. Despite setting up a $scope.$watch to trac ...