Inferno: Attempting to configurable attribute of unconfigurable property error under safari 7

Created on 22 Feb 2017  路  27Comments  路  Source: infernojs/inferno

Observed Behaviour

Inferno is raising an Attempting to configurable attribute of unconfigurable property. error when firing event handlers in Safari 7.0.6, preventing the handler from being run.

Attached is the screenshot of our error reporting tool.

screen shot 2017-02-22 at 16 25 37

Expected Current Behaviour

Inferno should fire the handler

Inferno Metadata
Inferno 1.3.0.rc.3
useragent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2

bug

Most helpful comment

Due to high demand from community for currentTarget we will re-introduce it in next release.

All 27 comments

does this happen in 1.2.2?

@longlho Looks like it, yes :(

about the history of this property, It was added there by my request. When using native javascript event listeners you can read currentTarget (click) from event parameter. When using synthetic events that currentTarget is obviously always document.

I'm not even using that property anymore and I wonder if we can just drop it?

Is safari7 supported anyway? We are running tests for Safari 9 and 10

I just removed these code in my project, and I wonder if these will be some side-effect ?

currentTarget won't be available in click events, no other change. Or more specifically: not available in synthetic events, regular events onclick={} (case sensitive) will work as they do in DOM standard.

I'm seeing this with PhantomJS 2.1.1 on macOS Sierra.

This error occurs when my test triggers a button click: $node.find('button')[0].click();

TypeError: Attempting to configurable attribute of unconfigurable property.

Using Karma, Mocha, Chai, and the related plugins to run the test.

I can't see a stacktrace but the error occurs even when I've stripped all of my event handler logic, and this didn't occur a few months when I originally started this work with inferno (I was using 1.0.0-beta23, am now using 1.4.2).

I can confirm it's the same block of code this issue was filed for:

Object.defineProperty(event, 'currentTarget', {
  configurable: true,
  get: function get() {
    return eventData.dom;
  }
});

Changing the currentTarget to a fake property doesn't trigger an error.

Lets drop this property, if it is absolutely needed for somebody he/she can use onclick instead of onClick. Also recommended way to use click events is to do linkEvent which makes this property useless.

Closing as 1.5 has been released! 馃憤

Thanks, the update solves the error, but it seems like at least in PhantomJS, triggering a click on an element via jQuery fails to fire a click handler on a component.

In my test I have:

$node.find('> .title').click();

In my component I have:

return <a onClick={this.onClick.bind(this)} />;

The test runs, the click() call is executed, but the onClick listener is never executed. I know from this previous error inferno was at least processing the click event, but for whatever reason it's not making it through to my component.

(and this all works as expected when used manually in Chrome)

@viveleroi has the <a> been appended to the document or is it detached?

make sure you have attached the node to document where you rendered your content

Yes, my tests create and append a DIV to the document.body and the library I'm testing renders to that element.

@viveleroi can you do document.querySelector('.title').click()?

Good thought, but no go. I verified document.querySelector('.title') was giving me a valid element, but onClick is still not triggering.

@viveleroi can you make a test repo? This sounds like a bug in Phantom. I remember there being a bug in Safari on iOS a while back where you couldn't fire click on <a> tags due to privacy of it auto opening links the user didn't want.

I'll try, not sure if I'll have to reproduce this in another repo. You're probably right, PhantomJS has a track record of crap like this but it presents an issue with my project.

@viveleroi Personally, I'd never touch Phantom again after the years of pain I had battling it. I just scrapped it and used JSDOM in the end. You could also try headless Chrome? Don't let your tooling slow you down if you can avoid it.

no reason to use Phantom these days [1], masochism aside.

[1] https://github.com/segmentio/nightmare

I'm definitely am eager to throw out Phantom so thanks for the recommendations. Using the Chrome launcher for karma, the tests pass only when I use document.querySelector('.title').click() and not the jQuery version. I don't mind removing jQuery from my tests, I'm only using it for a few things I can easily do natively, but figured you should know.

@viveleroi Glad you made some progress tonight :)

I would petition to have event.currentTarget be a reference to the node that the event handler was attached to. The only way I would ever be able use inferno is to swap it back and forth with React, and in React I believe currentTarget is normal/necessary for use. (And there is no linkEvent.)
for example:

export default class Grid extends Component {
  handleCellClicked = (event) => {
    let cellNumber = Number(event.currentTarget.dataset.id)
    this.props.onSelectionChange(this.props.gridName, cellNumber)
  }
  render () {
    let gridElements = []
    for (let cellNumber = 1; cellNumber < totalCells + 1; cellNumber++) {
      gridElements.push(
        <span data-id={cellNumber} style={{width: this.props.cellWidth, height: this.props.cellWidth}}
              key={cellNumber}
              onClick={this.handleCellClicked}>
            <span style={{paddingTop: 3}}>
              { '' + (cellNumber) }
            </span>
          </span>
      )
    }
    return (
      <table style={{display: 'inline-block'}} width='100%' height='100%'>
        <tbody>
        { gridElements }
        </tbody>
      </table>
    )
  }
}

So there's no bind() per element, and currentTarget and currentTarget.dataset work together so everything is efficient. But if I try switching to using inferno, I wouldn't be able to go back and forth because of the mandatory code change swapping linkEvent stuff with currentTarget.
see also: https://facebook.github.io/react/docs/events.html

This is a concern of ours re: switching between React and inferno-compat as well- makes it a little difficult to plug and play.

@trueadm @Havunen It's not only about dataset on element. I use this to have more isolated event handlers. I don't want to pass DOM elements as props to get it size on mouseMove.

Due to high demand from community for currentTarget we will re-introduce it in next release.

There is no guarantee that currentTarget will work in Safari7 or PhantomJS

As @Havunen said, this should have been fixed now. If it's not then please reopen.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davedbase picture davedbase  路  47Comments

devanp92 picture devanp92  路  20Comments

ilyaigpetrov picture ilyaigpetrov  路  21Comments

trueadm picture trueadm  路  25Comments

aprilmintacpineda picture aprilmintacpineda  路  22Comments