If state is true to play youtube video, and it is false I would like to delete youtube playing.
MY code is as follows.
{this.state.isPreViewVideo && <PlayYouTube video_id="ScSn235gQx0" />}
sandbox URL:
https://codesandbox.io/s/xryoz10k6o
Reproduction method:
If 4-digit characters are included in input form, "isPreViewVideo: true" by setState and if it is less than false
It works fine when state is true,
but when state is false, I encounter this error as follows.
DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
is there a way to avoid or resolve this error?
In playYouTube.tsx line 78 replace <React.Fragment>...</React.Fragment>
with <div>...</div>
Fragments let you group a list of children without adding extra nodes
to the DOM.
This explains the error
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
More on fragments here https://reactjs.org/docs/fragments.html
This error, Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node, can also be raised if Google Translate is used (or any other plugin that changes the page DOM).
This is detailed in this Github issue: https://github.com/facebook/react/issues/11538
Problem explanation:
When isPreViewVideo is truthy, you have this:
<PlayYouTube video_id="ScSn235gQx0" />
That probably renders to something like this:
<div> <!-- the root element as rendered by PlayYouTube if isPreViewVideo is truthy -->
<embed /> <!-- the video player or whatever PlayYouTube renders -->
</div>
Now if some code removes the player by directly manipulating the DOM and removing the root div, you'll end up with... Well, with nothing.
But in React's virtual DOM, the root div still exists! So when isPreViewVideo goes falsy, React tries to remove it from the real DOM but since it's already gone, the error is thrown.
The solution:
To expand on #henrik123's answer - wrapping PlayYouTube with a div like this...
<div> <!-- the root element rendered if isPreViewVideo is truthy -->
<PlayYouTube video_id="ScSn235gQx0" />
</div>
...causes this to render:
<div> <!-- the root element rendered if isPreViewVideo is truthy -->
<div> <!-- the element as rendered by PlayYouTube -->
<embed /> <!-- the video player or whatever PlayYouTube renders -->
</div>
</div>
Now the same code that removes the player by removing its root div makes it look like this:
<div> <!-- the root element rendered if isPreViewVideo is truthy -->
</div>
Now when isPreViewVideo goes falsy, the root exists both in React's virtual DOM and in the real DOM so there is no problem in removing it. It's children have changed but React doesn't care in this case - it just needs to remove the root.
Note:
Other HTML elements but div may work too.
Note 2:
Wrapping with React.Fragment instead of a div would not work because React.Fragment doesn't add anything to the real DOM. So with this...
<React.Fragment>
<PlayYouTube video_id="ScSn235gQx0" />
</React.Fragment>
...you still end up with this:
<div> <!-- the root element as rendered by PlayYouTube if isPreViewVideo is truthy -->
<embed /> <!-- the video player or whatever PlayYouTube renders -->
</div>
And you have the same issue.
TL;DR solution:
Wrap PlayYouTube with a div.
This error can occur when you use external JS or jQuery plugins. Let me tell about my case.
Issue description
In my React project I have some links on a page, every link opens a modal with some info and a slider with images inside it. Every link has its own set of images inside the slider. But I have the single modal, it is the same for every link.
Data for modal is stored in a state variable and I change its content on every link click (on every modal open):
const initialData = { title: "", intro: "" }; // here is some empty structure of object properties, we need it for the modalResponse initialization
const [modalData, setModalData] = useState(initialData);
// ...
<div id="MyModal">
<div className="title">{modalData.title}</div>
<div className="intro">{modalData.intro}</div>
<div>{modalData.sliderHtml}</div>
</div>
When I open modal using setModalData() I fill modalData with some new data. HTML-code inside modalData.sliderHtml is something like this structure:
<div class="carousel">
<div class="item"><img src="first.jpg" /></div>
<div class="item"><img src="second.jpg" /></div>
<div class="item"><img src="third.jpg" /></div>
</div>
When modal has opened I call some jQuery code for slider initialization:
useEffect(() => {
$('.carousel').initCarousel({
// some options
});
}, [modalData]);
Then user could close the modal and click the next link. The slider must be filled by new set of images. But I get the error: Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
Error reason
The reason of the issue is in a fact that the jQuery plugin changes the structure of html during initialization. It creates some new blocks inside the .carousel parent (arrows to the left/right, dots for navigation, etc.). And it moves all the .item children inside the new .items block! I get such html structure after the plugin initialization:
<div class="carousel">
<div class="dots">...</div>
<div class="arrows">...</div>
<div class="items">
<div class="item"><img src="first.jpg" /></div>
<div class="item"><img src="second.jpg" /></div>
<div class="item"><img src="third.jpg" /></div>
</div>
</div>
When React tries to change the content of modalData.sliderHtml it executes some magic DOM operations for old structure removing. One of this operations is removeChild method, but the old .item elements can't be found inside the parent .carousel because the plugin moved them inside the new .items element. So, we get the error.
Bug fixing
I started to change modalData content back to the initialData structure every time when the modal is closed.
useEffect(() => {
$('#MyModal').on('hidden.bs.modal', function (e) {
setModalData(initialData);
})
}, []);
So, all html structure inside modalData.sliderHtml is filled by the initial empty data again and we don't get an error on the new link click.
SOLVED for bootstrap alert after manually close button
I had exact error when i close the bootstrap alert error message if it's there manually and then submit the form again. what i had done is to wrap up the AlertError component with extra tag around.
import React from "react";
const AlertError = (props) => {
return (
<div> // <---- Added this
<div className="alert alert-custom alert-notice alert-light-danger fade show" role="alert">
<div className="alert-icon"><i className="flaticon-warning"></i></div>
<div className="alert-text">There is an error in the form..!</div>
<div className="alert-close">
<button type="button" className="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true"><i className="ki ki-close"></i></span>
</button>
</div>
</div>
</div> // <---- Added this
);
};
export default AlertError;
I had same problems with a audio tag and I kept this tag within two nested div and now its working
Most probable cause: something modified the DOM after React
The most probable cause of this issue is that something other than React modified the DOM after React rendered to it.
What's causing this DOM mutation?
Depending on the profile of users who are impacted, there might be a few different causes.
Everyone
If all your users are impacted, you, the developer might be the culprit.
The cause is probably that you are using jQuery or doing DOM manipulations outside of React.
Usual users
If usual users are affected, the most probable cause is Google Chrome translate feature (or Microsoft translate on Edge Chromium).
Thankfully there's an easy solution for that: add a <meta> tag in your HTML <head> (Google documentation).
<meta name="google" content="notranslate" />
This should also disable Microsoft Translator on Edge Chromium.
Advanced users
If only advanced users are affected, and they are not using a translation feature on their browser, then it might be a browser extension or some userscript (most likely run by SpiderMonkey) that causes the problem.
More info
Issue on React repo
SolidJS is also affected
Issue on Chromium bug tracker (please star it to help prioritize it)
This is a very annoying bug to fix. But you should wrap the component that you are rendering it conditionally with span element.
Check this GitHub issue: https://github.com/facebook/react/issues/11538#issuecomment-390386520
In one place of our code was something like this:
render() {
if (el) return <div />
return '';
}
After replacing ' ' with null, all works without errors.
I had the same issue with react. The problem was caused by a google-auth script tag in index.html.
<script src="https://accounts.google.com/gsi/client" async defer></script>
This is while I had another on the JS file causing the issue. Be sure to check for conflicting or repeated CDNs.
In my case, I just needed to reset the state OR make it to initial data when I needed to render it with new data. It fixed the issue.
Ex:
This issue occurred when I was setting table data upon getting API response in useFetch. Before setting the data to state, I first set it to initial value.
setTableData([]);
setTableData(data.response);
I hope it may help someone.
Node.removeChild() - Web APIs | MDN
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
fix:
unmountContainer() {
// macro task
setTimeout(() => {
// refs
if (containerEle) {
// receive removed node
// eslint-disable-next-line no-unused-vars
let removedChild = document
.querySelector('.page__wrapper')
.removeChild(containerEle);
}
});
}
In the main template for our Angular 4 application, which is sort of the 'root' template. It contains the container elements for the content area of the page and a sidebar off to the side.
Everything is working great except for older browsers (our customers are very large companies that only have older IE's, so we have to support IE10 and IE11) where the app is really unresponsive (in terms of UI updating and css transitions framerate).
One thing I noticed is that even if I rely on change detection that's purely inside the scope of the main app component, it triggers and executes all of the template code for all of the child components (4 times, in fact).
Here's the main part of my template:
<div class="page-content sidenav-open" id="page-content" #pageContent (window:resize)="adjustMainContent()">
<div [class]="'sidenav ' + (isAnimating ? 'isanimating' : '')" [style.width.px]="sidebar.width" [style.marginLeft.px]="sidebar.isVisible ? 0 : -sidebar.width">
<div class="vertical-resize-bar" (mousedown)="dragStart($event)"> </div>
<div class="sidenav-widget search-widget">
<app-navigation>Loading navigation...</app-navigation>
</div>
</div>
<div [class]="'main-content ' + (isAnimating ? 'isanimating' : '')" (transitionend)="isAnimating = false" [style.width.px]="mainContentWidth">
<router-outlet></router-outlet>
</div>
</div>
Again, functionally, it works great (in Chrome and Firefox, etc...), but not older browsers/computers. I just want those variables in my template snippet there to not trigger change detection on the app-navigation component and its children and whatever component gets loaded into router-outlet.
Am I doing anything (or multiple things) obviously wrong here? I should mention that this is our first Angular app.
I am new to web development and building an application using polymer 1.0.4. I am using the page.js routing similar to the example in start kit. Now many of the custom element that I built are using ajax and periodically refresh the data. The problem with page.js routing that It seems it loads all custom elements even if the element is not viewed by user. so all custom elements are loading the data even if it is not needed. my questions:
1- How could I fix this so the the elements load data only when they are viewed by the end users? Should I change the routing to another options like more-routing?
2- if the user filled the data in one custom element , then clicked on link to another element. The data will remains when the user goes back to the first custom element? How could I reset the polymer and html elements in the custom element when the use back to an old view?
Again, I'd recommend https://github.com/PolymerLabs/more-routing Eventually a 'carbon' (if I recall the name correctly) set of components will deal with this, according to the polymer summit videos, but until then this seems the standard approach.
Set up the pages via:
<more-routing-config driver="hash"></more-routing-config>
<more-route name="one" path="/one"></more-route>
<more-route path="/two">
<more-route name="two" path="/:name"></more-route>
</more-route>
Then the menu via:
<more-route-selector>
<paper-menu selected="0">
<paper-item route="{{urlFor('one')}}">One</paper-item>
<paper-item route="{{urlFor('two', {name: 'sup'})}}">Two</paper-item>
</paper-menu>
</more-route-selector>
And then the actual pages via:
<more-route-selector selectedParams="{{params}}">
<iron-pages selected="0">
<section route="one">
<div> Page one </div>
</section>
<section route="two">
<div> Page two: {{params.name}} </div>
</section>
</iron-pages>
</more-route-selector>
I used it when it was under the Polymore repository on github, and the samples above are from such, but it doesn't seem to have changed that much in its new home.
After you've set up the basics, listen for changes on the iron-pages, such as events that are available here. In such listeners, you can load the data for each section in iron-pages. One approach would be to use such listeners to call a method of a custom element, perhaps using a behaviour, that then brings down the data.
Try dna-router. You can create define states and routes in HTML only.
Setup routes by:
<dna-new-state state='home' route='/home'></dna-new-state>
<dna-new-state state='user' route='/user/:id/'></dna-new-state>
Create views by:
<dna-view
state='home'
element='home-template'></dna-view>
You can get all params inside your home-template polymer properties.
var params = this.params
For a detailed documentation, visit : https://github.com/Saquib764/dna-router
Firstly, the PolymerLabs/more-routing library is a nice alternative to page.js and is quite easy to implement. As this library is more declarative you can do things like:
routes.html
<more-routing-config driver="hash"></more-routing-config>
<more-route name="myRoute" path="/my-route-path/:id"></more-route>
app-element.html
<dom-module id="app-element">
<style>
iron-selector > * {
display: none;
}
iron-selector > .iron-selected {
display: block;
}
</style>
<template>
<more-route-selector>
<iron-selector>
<x-element></x-element>
</iron-selector>
</more-route-selector>
</template>
<script>Polymer({ ... });</script>
</dom-module>
x-element.html
<dom-module id="x-element">
<template>
<more-route id="route" context name="myRoute" params="{{params}}" active="{{activeRoute}}"></more-route>
</template>
<script>
Polymer({
is: 'x-element',
observers: [ '_paramsChanged(activeRoute, params.id)' ],
_paramsChanged: function(activeRoute) {
if (activeRoute) {
// Active route
} else {
// Inactive route
}
}
})
</script>
</dom-module>
Check out the polyfora app in the demo folder of the repository.
Otherwise, to use page.js I would consider:
Remove any auto iron-ajax queries in custom elements;
Pass a state attribute to custom elements;
Add an observer to any state changes within each custom element which triggers a function to run any iron-ajax queries.
As of Polymer 1.4, carbon-route (later renamed app-route) can be used:
https://github.com/polymerelements/carbon-route
https://blog.polymer-project.org/announcements/2016/03/28/carbon-route-released/
https://www.polymer-project.org/1.0/articles/routing.html
Here's an example taken from the polymer blog:
<carbon-location route="{{route}}">
</carbon-location>
<carbon-route route="{{route}}" pattern="/tabs/:tabName" data="{{data}}">
</carbon-route>
<paper-tabs selected="{{data.tabName}}" attr-for-selected="key">
<paper-tab key="foo">Foo</paper-tab>
<paper-tab key="bar">Bar</paper-tab>
<paper-tab key="baz">Baz!</paper-tab>
</paper-tabs>
<neon-animated-pages selected="{{data.tabName}}"
attr-for-selected="key"
entry-animation="slide-from-left-animation"
exit-animation="slide-right-animation">
<neon-animatable key="foo">Foo Page Here</neon-animatable>
<neon-animatable key="bar">Bar Page Goes Here</neon-animatable>
<neon-animatable key="baz">Baz Page, the Best One of the Three</neon-animatable>
</neon-animated-pages>
See also similar question: Polymer 1.0 - routing
It doesn't seem possible to extend the view for mobile. I would like to do so because I can predefine some options and behavior. I have create a sample here illustrating the problem, which gives me an error of:
Your kendo mobile application element does not contain any direct child elements with data-role="view" attribute set. Make sure that you instantiate the mobile application using the correct container.
JavaScript:
kendo.mobile.ui.plugin(kendo.mobile.ui.View.extend({
init: function (element, options) {
kendo.mobile.ui.View.fn.init.call(this, element, options);
},
options: {
name: 'ViewCustom'
}
}));
$(function () {
new kendo.mobile.Application(document.body);
});
HTML:
<section data-role="layout" data-id="default">
<header data-role="header">
<div data-role="navbar">My App</div>
</header>
<footer data-role="footer">
<div data-role="tabstrip">
Home
</div>
</footer>
</section>
<div id="home" data-role="viewcustom" data-layout="default">
Welcome to the home page!
</div>
http://jsfiddle.net/basememara/67RZN/
Kendo support simply said it's not supported - the mobile application does not recognize the descendants and does not initialize them upon start. This is a huge extensibility roadblock for mobile, so I've been poking around the source code to see where this is hard coded and I think the change will be somewhere in ViewEngine in kendo.mobile.view, possibly in _hideViews. I also see some hard coded views in kendo.mobile.pane. So I think this will be a big hack of the source code to get it working.
My question is there a way to extend the view without creating a new class, such as using prototype to extend kendo.mobile.view? Any help, experience, or insight will be greatly appreciated!
Instead of relying on Kendo to find the initial view to display, which will search specifically for data-role="view" you can instead programmatically tell it the initial view:
new kendo.mobile.Application(document.body, {
initial: "home"
});
I updated your example (and clicking the "Home" button also navigates to a second view just to make sure that worked as well).
I'm running into some odd behavior when putting an ngInclude inside an ngIf or ngSwitch.
For example, take the following:
<button ng-click="showIncTemplate = !showIncTemplate">Toggle Included Template</button>
<button ng-click="showInlineTemplate = !showInlineTemplate">Toggle Inline Template</button>
<div ng-if="showIncTemplate">
<p>Included template:</p>
<div ng-include="'template.html'"></div>
</div>
<div ng-if="showInlineTemplate">
<h1>Inline Template</h1>
</div>
(http://plnkr.co/edit/gULbwnKb0gQS8DWz0V6U)
The buttons toggle an options to render the divs that follow. The inline example behaves as expected, with the content appearing or disappearing on click.
The div with the child include seems not to include the template when first drawn, but then includes it repeatedly on every subsequent redraw.
What's going on here? I do see some breaking changes around ngInclude, is there some other way I should be doing this? Or is this a bug in Angular?
Edit:
It looks like this is already in the angularjs github issue tracker:
https://github.com/angular/angular.js/issues/3627
They've fixed it in this snapshot:
http://code.angularjs.org/snapshot/