VIN Decoder App
by Nicholas Berlette
HTML
<script src="https://unpkg.com/@unocss/runtime/attributify.global.js"></script>
<div id="app" style="opacity:0;transition:opacity 0.666s ease-in 0.2s;" class="wrapper !opacity-100" un-cloak>
<noscript>Please enable JavaScript to use this app.</noscript>
</div>
<script type="module">
import { html as h, Component, render } from 'https://esm.sh/v86/[email protected]/es2022/preact/standalone.module.js';
const $ = document.querySelector.bind(document);
const $$ = document.querySelectorAll.bind(document);
const store = {
$data: {},
get(key, fallback = []) {
try {
return JSON.parse(localStorage.getItem(key));
} catch {
try {
localStorage.setItem(key, JSON.stringify(fallback));
return this.get(key, fallback);
} catch {
return fallback;
}
}
},
set(key, value, fallback = []) {
try {
localStorage.setItem(key, JSON.stringify(value));
return this.get(key, fallback);
} catch {
try {
localStorage.setItem(key, JSON.stringify(fallback));
return this.get(key, fallback);
} catch {
return fallback;
}
}
}
};
class App extends Component {
async decode(input) {
const vin = input.value;
if (!vin || !vin.length || vin.length < 3)
return false;
const data = await fetch(`https://vpic.nhtsa.dot.gov/api/vehicles/decodevinvaluesextended/${vin}?format=json`)
.then(async r => r.ok && await r.json())
.then(d => Object.entries(d.Results[0] || {}))
.then(e => e.filter(([k,v]) => Boolean(v) && v != "" && v != "Not Applicable"));
this.setState({ data });
store.set('vin', vin);
store.set('vin_data', data);
}
render({ name = 'App', page = 'Home' }, {
data = store.get('vin_data'),
vin = store.get('vin')
}) {
let dataURI = '';
const datestr = new Date().toJSON().replaceAll(":", "-").replace(/\..+?$/, "");
let filename = `vindecoder_${datestr}.json`;
// attributions added...