Cannot get document keydown events with Object.assign

79 Views Asked by At

I am using

sources.DOM.select('document').events('keydown')
  .map(ev => Object.assign({}, ev, {type: 'keydown'}))

but the resulting stream gives objects with just the "isTrusted" property (and not "key", "code", etc.). Instead, with 'mousemove' I get events as expected (with "isTrusted" but also "movementX", "movementY", etc.). What is wrong?

1

There are 1 best solutions below

2
On BEST ANSWER

You're right, not a Cycle.js problem but rather a limitation of Object.assign.

Simply put—Object.assign does not copy inherited properties.

This answer on a similar problem provided a working alternative:

function main (sources) {
  const vdom$ = sources.DOM.select('document').events('keydown')
    .map(ev => cloneEvent(ev))
    .map(mykey => div('Key pressed: ' + mykey.key + ', code:' + mykey.code))
    .startWith(div('Press a key.'))

  return {
    DOM: vdom$
  }
}

function cloneEvent(e) {
  if (e===undefined || e===null) return undefined;
  function ClonedEvent() {};  
  let clone=new ClonedEvent();
  for (let p in e) {
    let d=Object.getOwnPropertyDescriptor(e, p);
    if (d && (d.get || d.set)) Object.defineProperty(clone, p, d); else clone[p] = e[p];
  }
  Object.setPrototypeOf(clone, e);
  return clone;
}

See updated codepen.io example.

These SO questions and answers also helped clarify the situation:

Poor Use Case of Object.assign() - Simple Example

Javascript hasOwnProperty always false on Event objects?