react-native: [0.59.x] URLSearchParams 'Error: not implemented'

šŸ› Bug Report

I used next code to check support URLSearchParams

if ( !global.URLSearchParams ) {
   global.URLSearchParams = require('url-search-params')
}

But now it doesnā€™t work because you add own ā€œimplementationā€ https://github.com/facebook/react-native/blob/e6057095adfdc77ccbbff1c97b1e86b06dae340b/Libraries/Blob/URL.js#L69-L71

And a canā€™t overwrite it

To Reproduce

const a = new URLSearchParams()
a.set('1','2');
a.toString()

Expected Behavior

My code donā€™t broken!

Remove these polyfills: https://github.com/facebook/react-native/blob/e6057095adfdc77ccbbff1c97b1e86b06dae340b/Libraries/Core/setUpXHR.js#L31-L32

Code Example

// I try force set custom 
global.URLSearchParams = require('url-search-params');

// But it works only with
import { polyfillGlobal } from 'react-native/Libraries/Utilities/PolyfillFunctions';

polyfillGlobal('URLSearchParams', () => require('url-search-params'));

Environment

  React Native Environment Info:
    System:
      OS: Linux 4.15 Linux Mint 19.1 (Tessa)
      CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
      Memory: 1.27 GB / 15.51 GB
      Shell: 2.7.1 - /usr/bin/fish
    Binaries:
      Node: 10.15.3 - /usr/bin/node
      Yarn: 1.13.0 - /usr/bin/yarn
      npm: 6.4.1 - /usr/bin/npm
    npmPackages:
      react: ^16.8.1 => 16.8.4 
      react-native: ^0.59.0 => 0.59.0 
    npmGlobalPackages:
      react-native-cli: 2.0.1

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 22
  • Comments: 24 (5 by maintainers)

Most upvoted comments

@matthargett the non-standard-compliant polyfill will cause issues because many 3rd-party libraries uses the global URL. I donā€™t think itā€™s reasonable to expect every app developer to throughly test whether this customised URL implementation is compatible with all the libraries. (That is why we have web standards in the first place.)

Many React Native applications use the included URL and URLSearchParams without issues

As you can see from the comments above, the new version breaks peopleā€™s apps with an obscure error even if it was working before. It means a breaking change was introduced without any documentation or workaround.

  1. If this URL implementation is intended to be used by app developers, it should be standard-compliant. I think URL and URLSearchParams are included in JavaScriptCore which is already provided by React Native 0.59. If that is the case, I donā€™t understand why we still need this customised URL implementation.

  2. If this URL implementation is only intended to be used internally by Blob, it should not be exported to the global scope. Or it should be renamed to something like RNURL to avoid confusing. App developers can actively decide if they want to use this customised version of URL.

In any case, its behaviour should be documented in some way. And a clear workaround should be provided with the error message.

// index.js

import { URL, URLSearchParams } from 'whatwg-url';
import { Buffer } from 'buffer';


// react-native 0.59 add own global URLSearchParams without implementation
// https://github.com/facebook/react-native/blob/e6057095adfdc77ccbbff1c97b1e86b06dae340b/Libraries/Blob/URL.js#L66
global.Buffer = Buffer;
global.URL = URL;
global.URLSearchParams = URLSearchParams;

Hey! I used an other npm package and had fixed it. search-params

Why is this closed? This is still an issue in 0.61.5

Hi @leethree , thanks for your comments.

Because URL needs to integrate with React Nativeā€™s blob support to enable an opaque reference that avoids huge copies, the URL is customized. Many React Native applications use the included URL and URLSearchParams without issues, even via complex libraries such as apollo-server. Iā€™m open to suggestions (and especially PRs) that are able to meet the needs.

In the meantime, Iā€™m happy to submit a PR myself to fix specific use cases that happen via libraries (such as apollo-server, etc). If you can tell me the use case, I can create a PR with tests pretty quickly.

@matthargett I think the polyfill should be removed from global because itā€™s not standard compliant and itā€™s not documented properly in React Native JavaScript Environment.

Even the most basic use case will result in broken URL because of this polyfill. I filed a new issue #24428 for it.

I would argue that a broken or incomplete polyfill is worse than no polyfill at all. Exposing it in global will let people assume itā€™s safe to use it.

Iā€™m also having this issue.

Thanks @A-Tokyo, thatā€™s what I went with in the end, it works like a charm. But still some recommended solution from the maintainers would be better instead of a workaround.

The only way I can get this to work, for example with aws-amplifyā€™s oauth, is to not only polyfill URLSearchParams as mentioned above, but to also delete the global reference: delete global.URLSearchParams;

This causes other issues, so Iā€™d love to hear if anyone has found a more reliable solution.

Hi! Yes, we purposefully didnā€™t bring in the full whatwg-url package because it has a major impact on the bundle size due to needing to support many unicode corner cases. I expanded our narrow implementation slightly to support apollo-serverā€™s use of URL. Is there a specific library that isnā€™t interacting properly?

Once you narrow the use case, I can suggest what can be done. If you need the fully spec-compliant URL implementation for reasons you canā€™t specify publicly, then the workaround in the comment above will work (at the cost of the bundle size impact).

This seems like an excellent candidate to add to the React Native documentation.

@halileohalilei Check my comment above, it should solve your issue šŸ‘

Iā€™m facing this issue at 0.61.5 as well

+1 @florian-milky Iā€™m facing this issue at 0.61.5 as well

This is whatā€™s working for me.

// index.js
import 'node-libs-react-native/globals';
import { polyfillGlobal } from 'react-native/Libraries/Utilities/PolyfillFunctions';

polyfillGlobal('URLSearchParams', () => require('whatwg-url').URLSearchParams);