How to get and set JSON data with Webtask storage?

159 Views Asked by At

Trying to figure out how to save mouse coordinates to Webtask storage after reading this post: https://blog.codepen.io/2018/05/04/say-you-need-to-get-set-some-json-data-from-a-pen/

I want to create a heatmap that will write mouse coordinates to Webtask storage when user clicks inside a div. And loads the updated data on page load.

This is what I got so far

const webtask_url = `https://wt-944eb9b4c90e6c80852f9671db4a1404-0.sandbox.auth0-extend.com/heatmap`;

var canvas = document.querySelector("canvas");
var ctx=canvas.getContext("2d");
var style = getComputedStyle(document.body);

canvas.width = parseInt(style.getPropertyValue('--s'), 10); 
canvas.height = parseInt(style.getPropertyValue('--s'), 10); 

//fill canvas
ctx.fillStyle = style.getPropertyValue('--c1');
ctx.fillRect(0, 0, canvas.width, canvas.height);

var mouse = {
  x: undefined,
  y: undefined
}

//get mouse position inside the div
function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect(), // abs. size of element
      scaleX = canvas.width / rect.width,    // relationship bitmap vs. element for X
      scaleY = canvas.height / rect.height;  // relationship bitmap vs. element for Y

  return {
    x: (evt.clientX - rect.left) * scaleX,   // scale mouse coordinates after they have
    y: (evt.clientY - rect.top) * scaleY     // been adjusted to be relative to element
  }
}

//click event
window.addEventListener("click", function(event){
  mouse.x = getMousePos(canvas, event).x;
  mouse.y = getMousePos(canvas, event).y;
  drawPoint(mouse.x, mouse.y);

  let data = {
    "x": mouse.x,
    "y": mouse.y
  };
  
//trying to send the coordinates to Webtask
  fetch(webtask_url, {
    method: 'post',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
    .then(response => response.json())
    .then(data => console.log('data is', data))

});

//draw a circle
function drawPoint(x, y) {
  ctx.beginPath();
  ctx.shadowBlur=10;
  ctx.shadowColor="rgb(233, 30, 99)";
  ctx.arc(x,y,5,0,2*Math.PI);
  ctx.fillStyle = style.getPropertyValue('--c2');
  ctx.fill();
}

//load coordinates from Webtask storage
fetch(webtask_url)
  .then(response => response.json())
  .then(data => {
  data.forEach(function(item, i) {
    drawPoint(item.x, item.y);
  });
});
:root {
  --bg: whitesmoke; 
  --c1: #5E35B1;
  --c2: #E91E63;
  --s: 300px;
  --shadow: 0 1em 5em -1em rgba(94, 53, 177, 0.8);
}

*{
  margin: 0;
  padding: 0;
  border: 0;
  box-sizing: border-box;
}

html,body {
  height: 100%;
  width: 100%;
  
}

body {
  background: var(--bg);
  font-family: "Open Sans", sans-serif;
  display: grid;
}

#canvas {
  display: grid;
  margin: auto;
  box-shadow: var(--shadow);
}
<canvas id="canvas"></canvas>

Webtask side

Author is updating color field in the Storage. My problem is that I am completely lost here. I understand I have to adjust ctx.storage.set part to accept my coordinates but I don't want to update them, I want to create a new entry in my JSON.

module.exports = function(ctx, cb) {

 if (Object.keys(ctx.query).length !== 0) {
   ctx.storage.set(ctx.query, { force: 1 }, function (error) {
      if (error) return cb(error);
      cb(null, { 
        "message": "success" ,
        "color": ctx.query.color
      });
   });
 } else {
   ctx.storage.get(function (error, data) {
      if (error) return cb(error);
      cb(null, data);
   });
 }

}
1

There are 1 best solutions below

0
On

If you want to append values to a list you'll need to store and manipulate an array instead of an object.

With ES6 the easiest way to do so is with the spread operator:

newData = [...oldData, newItem]

I've refactored your code a bit.

module.exports = (ctx, cb) => {
  ctx.storage.get((error, data) => {
    if (error) return cb(error)
    if (Object.keys(ctx.query).length === 0) {
      cb(null, data)
    } else {
      const newData = [...data, ctx.query]
      ctx.storage.set(newData, error => {
        if (error) return cb(error)
        cb(null, { "message": "success" , "color": ctx.query.color })
      })
    }
  })
}