Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ITML <Error>: Invariant Violation: processUpdates(): Unable to find child 0 of element. #13

Open
enjikaka opened this issue Nov 3, 2015 · 9 comments

Comments

@enjikaka
Copy link

enjikaka commented Nov 3, 2015

ITML <Error>: Invariant Violation: processUpdates(): Unable to find child 0 of element.
This probably means the DOM was unexpectedly mutated (e.g., by the browser), 
usually due to forgetting a <tbody> when using tables, nesting tags like <form>, 
<p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the 
child nodes of the element with React ID `.1ljayehovsw.1.0.0.1`.

I do not know how to check for .1ljayehovsw.1.0.0.1, can't find a way to debug this. But all my tags are closed correctly. This happens when I try to render <lockup> within <section> in a <grid>.

Snippet:

var React = require('react');
var TVML = require('react-tvml');


var ArtistAlbumListItem = React.createClass({
    render: function() {
        return (
            <lockup>
                <img src={this.props.album.cover} width="256" height="256" />
                <title>{this.props.album.name}</title>
            </lockup>
        );
    }
});

var ArtistAlbumList = React.createClass({
    render: function() {
        var albums = this.props.albums.map(function(album) {
            return (
          <ArtistAlbumListItem key={album.id} album={album} />
        );
        });

        return (
            <grid>
                <section>
                    {albums}
                </section>
            </grid>
        );
    }
});

var ArtistView = React.createClass({
    getInitialState: function() {
        return {
            albums: []
        }
    },
    componentDidMount: function() {
        var self = this;

        var artistId = self.props.id;
        var url = 'https://api.spotify.com/v1/artists/' + artistId + '/albums';

        console.log('I want to load JSON.');

        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.onreadystatechange = function() {
            if (xhr.status === 200 && xhr.readyState === 4) {
                var json = JSON.parse(xhr.responseText);

                var jsonAlbums = [];

                for (var i = 0; i < json.items.length; i++) {
                    var jsonAlbum = json.items[i];

                    jsonAlbums.push({
                        name: jsonAlbum.name + "",
                        cover: jsonAlbum.images[0].url + ""
                    });
                }


                if (self.isMounted()) {
                    self.setState({
                        albums: jsonAlbums
                    });
                }
            }
        };
        xhr.send();
    },
    render: function() {
        return (
            <catalogTemplate>
                <banner>
                    <title>CHVRCHES</title>
                </banner>
                <list>
                    <section>
                        <listItemLockup>
                            <title>Albums</title>
                            <relatedContent>
                                {this.state.albums.length > 0 ? <ArtistAlbumList albums={this.state.albums} /> : <activityIndicator><title>Loading</title></activityIndicator>}
                            </relatedContent>
                        </listItemLockup>
                    </section>
                </list>
            </catalogTemplate>
        );
    }
});

TVML.render(<ArtistView id="3CjlHNtplJyTf9npxaPl5w" />);
@sergioramos
Copy link
Owner

let me get back to you later ;)

@deanmcpherson
Copy link

Hey @ramitos, any update on this? I'm running into similar issues, where pretty much all dom mutations fail, I either get the same error as above or:

<Error>: Invariant Violation: dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering. - http://localhost:9001/public/bundle.js - line:1338:25

@adityaj221
Copy link

+1

@boffbowsh
Copy link

The issue is that React expects window and document global variables to be available at require-time. I've been trying to dig into the React internals enough to work out what I need to monkey-patch in this repo, but I'm struggling a bit. If anyone has any deeper React experience, please let me know :)

@boffbowsh
Copy link

Made some progress by using Browserify to inject window, document and navigator globals to classes that need them. I'm now coming up against issues in tvOS internals where an IKDOMNodeList (TVJS's version of a NodeList) is assumed by React to be indexable like list[3], but instead you should use list.item(3). This is actually a bug in TVML, and means that their NodeList implementation doesn't obey the specification. I'll try and sort out a workaround :)

@sergioramos
Copy link
Owner

@boffbowsh I haven't had time to look at this, but window is already being emulated: https://github.com/ramitos/react-tvml/blob/master/src/globals.js

@boffbowsh
Copy link

Yes indeed, I think I posted that after a lot of yak shaving. The root issue though is the IKDOMNodeList problem. I might try a beta of the new version of tvOS to see if the issue has been addressed.

@deanmcpherson
Copy link

From my experience the DOM implementation looks like it's not completely implemented. Even using list.item(X) syntax, modifying the DOM in some templates doesn't actually reflect itself visually either. This makes sense as the intention behind TVML looks like it encourages you would generate the templates server side and navigate between documents (web 1.0 style).

I built the Townske tvOS app using TVML my own React like framework I wrote for it, but will most likely rewrite it in swift (or React Native if proper support is picked up), as the restrictions imposed design wise by TVML and the lack of a fully functional DOM makes it quite difficult to bend it to your own needs.

@emadalam
Copy link

At present the whole TVJS seems a lot buggy and half baked when it comes to DOM api implementations. For instance something as trivial as querySelectorAll is missing, the dynamic update of the DOM causes the whole TVML template to distort in many occasions (try updating any node inside productTemplate), etc. So IMHO using any library that does DOM manipulation, is bound to be buggy. I had to completely drop the idea of using any external library and ended up writing one of my own, atvjs, built on top of TVJS.

Having said that, the ReactJS concept of virtual DOM and diff to issue partial updates to the DOM, may not work in many cases. The best bet is to regenerate the whole document and use replaceDocument method of TVJS navigationDocument class to completely replace the existing DOM with the newly generated one. This might not be the best of the solution, however at present, this is the only foolproof way of updating the DOM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants