obniz クラウドで MQTT.js subscribe 時の console.log で Uncaught TypeError: e.replace is not a function が出たときのメモ

obniz クラウドで MQTT.js で subscribe したときの message を console.log したときに Uncaught TypeError: e.replace is not a function が出てしまうときのメモです。

状況

たとえば、 obniz クラウドで MQTT over WebSocket したいときに MQTT.js を使って以下のようなコードを書いたときです。

どこかから publish されたメッセージを受け取るところで Uncaught TypeError: e.replace is not a function になります。

      var obnizDeviceMQTT = mqtt.connect("wss://id:pass@driver.cloudmqtt.com:18839");

      var pubTopic = "/pub/obniz";
      var subTopic = "/sub/obniz";

      var clientId = "obniz-seigo-" + new Date().getTime();

      obnizDeviceMQTT.on("connect", function () {
        console.log("obnizDeviceMQTT : connect success");
        obnizDeviceMQTT.subscribe(subTopic, function (e) {
          if (e) {
              // なぜか購読できないとき(認証エラーとか?
              console.log("obnizDeviceMQTT: Subscrib error", e);
            }
            else {
              console.log("obnizDeviceMQTT: Subscribed!! ");
              //
              var sendData = {
                "message": "Hello MQTT!!"
              };
              // 一度メッセージを送る
              obnizDeviceMQTT.publish(pubTopic, JSON.stringify(sendData));
            }
         });
      });

      // publish されたメッセージを受け取るところ
      obnizDeviceMQTT.on("message", function (topic, payload) {
        // メッセージ受信できたよログ
        console.log("message");
        console.log(payload);  // Uncaught TypeError: e.replace is not a function になる
      });

      obnizDeviceMQTT.on("error", function (topic, payload){
        console.log(payload);
      });

対処法

MQTT.js のサンプルにも書かれているのですが、日を開けて使うときに忘れがち。データの中身が Buffer なので payload.toString() にしてやることで文字列として扱えるようにするところがポイントです。

つまり、以下のようにして JSON として扱えるようにします。

      // publish されたメッセージを受け取るところ
      obnizDeviceMQTT.on("message", function (topic, payload) {
        // メッセージ受信できたよログ
        console.log("message");
        var jsonData = JSON.parse(payload.toString());
        console.log(jsonData);
      });

console.log(typeof(payload)); でデータを見てみると Uint8Array 型で帰ってくるので Buffer であることが分かります。JSON.parse(payload.toString()); で文字列に変換した後に JSON パースしています。

なんか、毎度毎度、フロントエンドでサッと使おうとするときに、このエラーでハマっている気がするのでまとめてみました!