LoginSignup
0
0

More than 1 year has passed since last update.

[JavaScript]URLSearchParams.toString()がnull値を"null"とするのを避ける為、nullをオブジェクトから除外する

Posted at

前提

 GET用のURLパラメータを構築する時、URLSearchParams.toString()が便利です。次のように使います。

const params = {
	search: "abc",
	searchtype: 2,
	userid: 1234,
}

const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
https://host/api/getXXX?search=abc&searchtype=2&userid=1234

問題点

 paramsのプロパティ値にnullやundefinedを含むものがあった場合、それらは"null"、"undefined"という文字列としてエンコードされます。

const params = {
	search: null,
	searchtype: undefined,
	userid: 1234,
}

const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
https://host/api/getXXX?search=null&searchtype=undefined&userid=1234

これは URLSearchParamsの仕様ではありますが、この仕様がサーバ側で役に立つケースはほぼないでしょう。
nullという入力値を本当にnullとして扱ってしまうと、今度は"null"という文字列を送信できないことになってしまう為です。

解決策(コード付き)

例えば ASP.NET Core等は、サーバ側でGET/POSTパラメータをモデルクラスにマッピングする際には、そのパラメータが存在しなければ自動的にデフォルト値(文字列やNull許容値の場合はnull、数値の場合は0)で初期化されます。

よって、paramsの中にnullやundefinedなプロパティがあれば、プロパティ自体を除外してしまえば良いでしょう。

オブジェクトからnullやundefinedなプロパティを除外して返す
function filterNullProperties(obj) {
    return Object.keys(obj).reduce(
        (retObj, key) =>
            (obj[key] === null || obj[key] === undefined)
                ? retObj    // null プロパティは無視
                : Object.assign(retObj, { [key]: obj[key] })    // null でないプロパティのみretObjに追加
        , {});
}

上記を用いると、次のような結果が得られます。

const params = filterNullProperties({
	search: null,
	searchtype: undefined,
	userid: 1234,
});

const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
https://host/api/getXXX?userid=1234

一見落着です。

気がかりな点

どうして URLSearchParamsがこのような仕様になっているのかが分からないのでその点は気がかりです。
null値を"null"という文字列にして送信することでうれしいケースがある、ということでしょうか?

また、もっとシンプルに書ける方法などありましたらコメントでご教授頂ければと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0