Reputation: 56753
I have the following function defined and run on DOMContentLoaded
(among others, not relevant here):
function dependentControls() {
const dependers = [...document.querySelectorAll('[data-depends-on]')]
for (const depender of dependers) {
let dependency = document.getElementById(depender.dataset.dependsOn)
if (dependency) {
let dependencyDetails = {
prop: null,
state: null
}
switch (dependency.type) {
case 'checkbox':
{
dependencyDetails.prop = 'checked'
dependencyDetails.state = false
break // this break exits the current for loop iteration
}
case 'text':
{
dependencyDetails.prop = 'value'
dependencyDetails.state = ''
break // this break exits the current for loop iteration
}
default:
console.log('default case')
}
console.log("switch...end") // this line is never reached
depender.disabled = !dependency[dependencyDetails.prop]
dependency.addEventListener('change', () => {
console.log('dependancy changed')
depender.disabled = dependency[dependencyDetails.prop] === dependencyDetails.state
})
}
}
console.log('for...end')
}
document.addEventListener('DOMContentLoaded', dependentControls);
<div>
<input type="checkbox" id="fooBar" />
<label for="fooBar">dependency</label>
</div>
<hr />
<div>
<label for="fooBaz">depender</label>
<input type="text" id="fooBaz" data-depends-on="fooBar" value="depender" />
</div>
This is the relevant part of the transpiled code:
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
var dependentControls = function dependentControls() {
var dependers = _toConsumableArray(document.querySelectorAll('[data-depends-on]'));
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
var _loop5 = function _loop5() {
var depender = _step5.value;
var dependency = document.getElementById(depender.dataset.dependsOn);
if (dependency) {
var dependencyDetails = {
prop: 'checked',
state: false
};
switch (dependency.type) {
case 'checkbox':
{
dependencyDetails.prop = 'checked';
dependencyDetails.state = false;
return "break";
}
case 'text':
{
dependencyDetails.prop = 'value';
dependencyDetails.state = '';
return "break";
}
default:
}
console.log("switch...end"); // this line is never reached
depender.disabled = !dependency[dependencyDetails.prop];
dependency.addEventListener('change', function() {
depender.disabled = dependency[dependencyDetails.prop] === dependencyDetails.state;
});
}
};
_loop4: for (var _iterator5 = dependers[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var _ret2 = _loop5();
switch (_ret2) {
case "break":
break _loop4;
default:
if (_typeof(_ret2) === "object") return _ret2.v;
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
console.log("for...end");
}
document.addEventListener('DOMContentLoaded', dependentControls);
<div>
<input type="checkbox" id="fooBar" />
<label for="fooBar">dependency</label>
</div>
<hr />
<div>
<label for="fooBaz">depender</label>
<input type="text" id="fooBaz" data-depends-on="fooBar" value="depender" />
</div>
This is my .babelrc
:
{
"presets": [
[ "@babel/preset-env", {
"targets": {
"browsers": [ "last 2 versions", "ie >= 11" ]
}
}]
]
}
I'm using Babel 7 to transpile the code and the latest webpack to bundle it. When I paste this code in the console and call the function, the problem does not occur. When I paste this code in http://babeljs.io/repl and paste the resulting code in the console, it also works.
By the looks of it, this has been reported in April already, with noone commenting on the issue so far:
https://github.com/babel/babel/issues/7765
Nonetheless I've also filed it:
https://github.com/babel/babel/issues/8709
Upvotes: 4
Views: 151
Reputation: 56753
Turns out that is really a bug introduced in Babel 7.
The reason it wasn't reproducable in the Babel REPL is that the official REPL is still on Babel 6.2.6. The 7.0 REPL is currently available here:
Babel 7 transpiles break
to return "break";
if the break
occurs in a case
block that is wrapped in curly braces:
This works as expected with Babel 7:
switch (a) {
case 1:
/** some code **/
break
default:
}
This creates the problem:
switch (a) {
case 1: { // <-- wrapping the case ...
/** some code **/
break
} // <-- ... makes Babel go wrong
default: {}
}
Wrapping the case in {}
makes Babel transpile the break
to return "break";
- which is clearly a bug on Babel side.
Just don't wrap case
instructions in a new block context {}
for now if you don't have to (the new block context in my original code was only for readability, so unnecessary anyway). Will update the answer when Babel has fixed that.
Upvotes: 2
Reputation: 12161
The code is working just fine, the console.log("switch end")
is executed as expected.
Make sure your babel version is updated.
You can check it working here: https://codepen.io/rafaelcastrocouto/pen/LJrRqj
'use strict';
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function dependantControls() {
var dependers = [].concat(_toConsumableArray(document.querySelectorAll('[data-depends-on]')));
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
var _loop = function _loop() {
var depender = _step.value;
var dependency = document.getElementById(depender.dataset.dependsOn);
if (dependency) {
var dependencyDetails = {
prop: null,
state: null
};
switch (dependency.type) {
case 'checkbox':
{
dependencyDetails.prop = 'checked';
dependencyDetails.state = false;
break; // this break exits the current for loop iteration
}
case 'text':
{
dependencyDetails.prop = 'value';
dependencyDetails.state = '';
break; // this break exits the current for loop iteration
}
default:
console.log('default case');
}
console.log("switch end"); // this gets never executed!
depender.disabled = !dependency[dependencyDetails.prop];
dependency.addEventListener('change', function () {
console.log('dependancy changed');
depender.disabled = dependency[dependencyDetails.prop] === dependencyDetails.state;
});
}
};
for (var _iterator = dependers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
_loop();
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
console.log('for...end');
}
document.addEventListener('DOMContentLoaded', dependantControls);
<div>
<input type="checkbox" id="fooBar" />
<label for="fooBar">dependency</label>
</div>
<hr />
<div>
<label for="fooBaz">depender</label>
<input type="text" id="fooBaz" data-depends-on="fooBar" value="depender" />
</div>
Upvotes: 0