Search code examples
javascriptweb-worker

How to receive JSON object from a webworker


Hi am stuck in a problem for retrieving a JSON object from a web worker, I am able to receive something like [object Object] which is not a JSON object. Following is my code.

main.js file

if (window.Worker) { // Check if Browser supports the Worker api.
    var worker;
    try {
         worker = new Worker("worker-data.js");
         worker.postMessage([{"data": [{"data1":30},{"data2":40},{"data3":3}]}]);
    } catch(error){
        console.log(error)
    }
}

worker-data.js file code

onmessage = function(message) {
    console.log(message.data);
}

Output I receive:-  [object Object] Output Expected:-  A JSON OBJECT sorry for the image alignment.


Solution

  • You are passing an array of object inside your post message

    worker.postMessage([{"data": [{"data1":30},{"data2":40},{"data3":3}]}]);
    

    Your array of object is there inside the data property of the message message.data but you are accessing it all wrong, Try accessing the first index of message.data

    message.data[0] which contains your object {"data": [{"data1":30},{"data2":40},{"data3":3}]}

    Use message.data[0].data to access the data of your object

    [{"data1":30},{"data2":40},{"data3":3}]

    Explanation:

    whatever you pass in your worker.postMessage will be there in message.data along with other properties of message and here what you passed is an array so you need to access the first index of the array to get your data

    message.data[0] and then access the data of your object passed message.data[0].data

    Inside your message

     onmessage = function(message) {
        console.log(message.data[0].data);
        console.log(message.data[0].data[0].data1);
        console.log(message.data[0].data[1].data2);
        console.log(message.data[0].data[2].data3); 
     };
    

    or

    Pass only object

    worker.postMessage({"data": [{"data1":30},{"data2":40},{"data3":3}]});

    then on your message access the data as message.data.data

    onmessage = function(message) {
            console.log(message.data.data);
            console.log(message.data.data[0].data1);
            console.log(message.data.data[1].data2);
            console.log(message.data.data[2].data3); 
         };
    

    Here is your updated fiddle https://jsfiddle.net/d7b680je/1/

    SNIPPET

    Check the console of snippet for output.

    try {
    
      var ww = document.querySelector('script[type="text/ww"]'),
        code = ww.textContent,
        blob = new Blob([code], {
          type: 'text/javascript'
        }),
        blobUrl = URL.createObjectURL(blob),
        worker = new Worker(blobUrl);
      let temp = {
        "dataVal": [{
          "data1": 30
        }, {
          "data2": 40
        }, {
          "data3": 3
        }, {
          "data4": 10
        }, {
          "data5": 130
        }, {
          "data6": 140
        }]
      };
      worker.postMessage(temp);
    
    } catch (ex) {
      alert(ex);
    }
    <script type="text/ww">
      self.onmessage = function(message) { console.log(message.data.dataVal); console.log(message.data.dataVal[0].data1); console.log(message.data.dataVal[1].data2); console.log(message.data.dataVal[2].data3); };
    </script>

    I recommend you remove all arrays and pass your data as objects

    Check this fiddle https://jsfiddle.net/d7b680je/2/

    try {
    
      var ww = document.querySelector('script[type="text/ww"]'),
        code = ww.textContent,
        blob = new Blob([code], {
          type: 'text/javascript'
        }),
        blobUrl = URL.createObjectURL(blob),
        worker = new Worker(blobUrl);
      let temp = {
        "dataVal": {
          "data1": 30,
          "data2": 40,
          "data3": 3,
          "data4": 10,
          "data5": 130,
          "data6": 140
        }
      };
      worker.postMessage(temp);
    
    } catch (ex) {
      alert(ex);
    }
    <script type="text/ww">
     	 self.onmessage = function(message) {
            console.log(message.data.dataVal.data1);
            console.log(message.data.dataVal.data2);
            console.log(message.data.dataVal.data3); 
         };
    </script>

    Console log of above snippet and fiddle in mac safari

    enter image description here