Skip to content
Astera Technology

Read data attributes as strings before interpreting them

Interpret fixed data attributes only after inspecting their string values.

Download complete case notes and answer keys ↓

Inspect the fixed example

The paragraph supplies data-enabled="false" and data-line-count="3". Compare raw values, Boolean conversion, an explicit true check and numeric conversion.

Complete body and fixed script
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<p id="note" data-enabled="false" data-line-count="3">Workshop note</p><output id="result"></output>
<script>const data=document.querySelector('#note').dataset;const result={raw:data.enabled,type:typeof data.enabled,truthy:Boolean(data.enabled),explicit:data.enabled==='true',count:Number(data.lineCount)};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>
Exact console output
{"raw":"false","type":"string","truthy":true,"explicit":false,"count":3}
Inputs and native results
InspectionSupplied input or actionResult
enabled"false"type: string; truthy: true
Explicit flag ruleenabled==='true'false
lineCount"3"Number: 3

Follow the native mechanism

dataset exposes attribute values as strings and maps data-line-count to lineCount. A nonempty string such as false is truthy. Comparing with the literal true string implements this fixture’s flag rule; Number("3") converts this fixed valid input, not arbitrary data validation. Missing attributes yield undefined.

Compare the material alternative

Boolean is not a parser for the words true and false. Here a nonempty invalid number produces NaN after Number conversion; String keeps NaN visible rather than allowing JSON to turn it into null.

Fresh counterexample source
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<p id="note" data-enabled="false" data-line-count="three">Workshop note</p><output id="result"></output>
<script>const data=document.querySelector('#note').dataset;const result={enabled:Boolean(data.enabled),numeric:String(Number(data.lineCount))};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>
Counterexample output
{"enabled":true,"numeric":"NaN"}

Work the boundary

What is the difference between a missing data-enabled and an explicitly empty one?

Show the worked answer

Missing gives undefined and no attribute; empty gives a present attribute and the empty string. Both Boolean conversions are false, so that conversion alone loses the distinction.

Fresh boundary source
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<p id="missing">Missing attribute</p><p id="empty" data-enabled="">Empty attribute</p><output id="result"></output>
<script>const missing=document.querySelector('#missing'),empty=document.querySelector('#empty');const result={missingType:typeof missing.dataset.enabled,missingPresent:missing.hasAttribute('data-enabled'),empty:empty.dataset.enabled,emptyPresent:empty.hasAttribute('data-enabled'),truthy:[Boolean(missing.dataset.enabled),Boolean(empty.dataset.enabled)]};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>
Boundary output
{"missingType":"undefined","missingPresent":false,"empty":"","emptyPresent":true,"truthy":[false,false]}

Original example files