Published
Edited
Dec 10, 2018
Importers
1 star
Insert cell
Insert cell
syncExample = download(() => {
return new Blob(
[JSON.stringify({hello: "world"})],
{type: "application/json"}
);
}, "helloworld.json", "Save a synchronous value with one click")
Insert cell
asyncExample = download(async () => {
await Promises.delay(1000);
return new Blob(
[JSON.stringify({hello: "world"})],
{type: "application/json"}
);
}, "helloworld.json", "Save an asynchronous value with two clicks")
Insert cell
Insert cell
b = {
const d = html`<button>Reset asynchronous download button`;
d.onclick = event => asyncExample.dispatchEvent(new CustomEvent("reset"));
return d;
}
Insert cell
function download(value, name = "untitled", label = "Save") {
const a = html`<a><button></button></a>`;
const b = a.firstChild;
b.textContent = label;
a.download = name;

async function reset() {
await new Promise(requestAnimationFrame);
URL.revokeObjectURL(a.href);
a.removeAttribute("href");
b.textContent = label;
b.disabled = false;
}

a.onclick = async event => {
b.disabled = true;
if (a.href) return reset(); // Already saved.
b.textContent = "Saving…";
try {
const object = await value();
b.textContent = "Download";
a.href = URL.createObjectURL(object);
} catch (ignore) {
b.textContent = label;
}
if (event.eventPhase) return reset(); // Already downloaded.
b.disabled = false;
};

a.addEventListener("reset", reset);
return a;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more