輝く僕らの学費

外の空気が大好き、そこそこ忙しい理系の男子大学生のぶちおです。

JS

[Vue.js] axiosで大きな整数を含むデータを取得する方法

投稿日:

経緯

Laravel + Vue.jsでTwitter APIを扱うWebアプリの開発をしていました。
Twitterのツイート個別のIDは、桁数が大きいため、DBで扱う際にもINTでは収まらないのでBIGINTを使ったりしています。

今回、Vue.jsからaxiosでデータを取得してJSの変数に格納すると、APIが返すIDと変数のオブジェクトが持つIDが一致していないことに気が付きました。

APIの出力

Vue.jsで持つデータ

大きな整数のときの挙動

json-bigintのReadmeに載っていた例と同じような挙動だったので、それに置き換えて示すと以下のようになります。
APIで返したIDの値とVue.jsのオブジェクトが持つIDの値です。
9223372036854775807
9223372036854776000
このように、大きな整数だと小さい位が丸められてしまっていることがわかりました。

あまり追求できてはいないですが、JSON.parse()では桁数の大きい整数はうまくパースできないということです。
そして、axiosはレスポンスデータをオブジェクトにする際に、JSON.parse()を使っているらしい。

BigIntでもJSON.parseのようにパースできるパッケージ「json-bigint」

NPMインストールで導入できます。

$ npm i json-bigint

axiosでjson-bigintのパースを使う

今回、問題となったツイートIDを使う場面は多いので、デフォルトのtransformResponseを設定することにしました。axiosで取得したデータを好きなように整形するオプションです。

この設定はapp.jsに記述しました。

// axios use JSON BIGINT Parser
const JSONbig = require('json-bigint');
axios.defaults.transformResponse =  [function (data) {
    return JSONbig.parse(data);
}]

個別に設定する場合は、paramsなどのオプションの部分でtransformResponseを設定できます。

axios.get(\"/api/method\", {
    params: {
        ...
    },
    transformResponse: [
        data => {
            return JSONbig.parse(data);
        }
    ],
})

動作確認

簡単にパースされた値を確認してみました。

console.log(this.tweets[0].id)
alert(this.tweets[0].id)

コンソールログ

これで見ると、BigNumberとしてオブジェクトのように格納されているようです。

alert()

コンソールログで見るとオブジェクトっぽく見えましたが、普通にthis.tweets[0].idのような形で使って大丈夫そうです。そのため、既にレスポンスデータを使っている箇所の変更は必要なさそうです。

VueのDevTool

一応、VueのDevToolでもオブジェクトのようになっているようです。

おわり

いっそのこと、文字列にしてしまうとかダサいやり方も考えましたが、スマートに対処できたのでよかったです。

参考リンク

-JS

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

no image

Vue.jsにElementを導入して簡単に綺麗なUIを使う

Element Vue.jsで使える、割とメジャーなUIフレームワーク Vue.jsのコンポーネントで定義されているので、簡単に綺麗なUIコンポーネントを置いて使うことができる。 使用する環境 Lar …

no image

ビルド環境をParcelにしてみたけど、結局webpackにした

Parcel JSやCSSのビルド環境として、Parcelを導入しました。 parcel index.html このように設定いらずがコンセプトで、ファイルを指定するだけで依存関係のあるリソースをコン …