Public
Edited
Nov 24, 2022
37 stars
Also listed in…
Observable Things
Insert cell
Insert cell
Insert cell
[{name: "one"}, {name: "and two ..."}, {name: "and three!"}]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
html`<button>OK!</button>`
Insert cell
Insert cell
my_element = {
// The element (only created once, then passed around by reference).
const element = html`<b>I'm here!</b>`;
// An infinite loop.
while(true) {
// Detach the element from whereever in the DOM it currently is.
element.remove();
// Output the element, which attaches it to the DOM.
yield element;
// Wait two seconds.
await Promises.tick(2000);
}
}
Insert cell
Insert cell
{
// Wait a second.
await Promises.tick(1000);
// Detach the element from wherever in the DOM it currently is.
if(remove_element) my_element.remove();
// Output the element, which attaches it to the DOM.
yield my_element;
}
Insert cell
Insert cell
Insert cell
Insert cell
<span class="observablehq--inspect"><span class="observablehq--cellname">my_var = </span><span class="observablehq--string">"my value"</span></span>
Insert cell
Insert cell
Inspector = (await require('@observablehq/inspector')).Inspector
Insert cell
function inspect(value, name = null) {
// Create an empty element to attach the Inspector's HTML to.
const container = html`<div>`;
// Create a new Inspector instance and attach it to the container.
const inspector = new Inspector(container);
// Let the instance know that this is the new value that it should render.
inspector.fulfilled(value, name);

return container;
}
Insert cell
inspect('my value', 'my_name')
Insert cell
Insert cell
my_inspection = inspect('my value', 'my_name')
Insert cell
my_inspection
Insert cell
Insert cell
viewof my_other_inspection = {
// Note that we have to pass in the name manually here.
const element = inspect('my value', 'my_other_inspection');
element.value = 'Hey, that\'s not my value!';
return element;
}
Insert cell
my_other_inspection
Insert cell
Insert cell
Insert cell
Insert cell
viewof my_counter = Inputs.button('Count up')
Insert cell
Insert cell
my_counter
Insert cell
Insert cell
viewof my_counter
Insert cell
Insert cell
viewof my_counter.value
Insert cell
Insert cell
viewof my_2nd_counter = Inputs.button('Count up', {required: true})
Insert cell
viewof my_2nd_counter.value
Insert cell
my_2nd_counter
Insert cell
Insert cell
Insert cell
my_3rd_counter = Inputs.button('Count up')
Insert cell
Generators.input(my_3rd_counter)
Insert cell
Insert cell
viewof my_4th_counter = Inputs.button('Count up')
Insert cell
my_4th_counter
Insert cell
{
const output = html`<output>`;
yield output;
for await(const value of Generators.input(viewof my_4th_counter)) {
output.value = value;
}
}
Insert cell
Insert cell
viewof button_undefined = {
const element = html`<button>Click me!`;
Object.defineProperty(element, 'value', {value: undefined});
return element;
}
Insert cell
Insert cell
button_undefined
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof example_value = Inputs.range([0, 100], {value: 0, step: 1})
Insert cell
viewof filtered_value = {
// Create the view's DOM element. Later on we'll attach the value
// to the <div> element.
const element = html`<div><code><em>Further to the right!`;
// Create an Inspector instance for the element.
const inspector = new Inspector(element);
// Mark the output as "pending" (the gray bar to the left). Note that this will
// only set a class on the element, but *not* replace its contents.
inspector.pending();

// We haven't defined element.value yet, so it's still undefined.
// We'll only set it if our threshold of 50 is passed.
if(example_value >= 50) {
// Set the element's value property. This is what will be seen
// when we reference "filtered_value" (without the viewof prefix).
element.value = example_value;
// Have the inspector show the value. This replaces the element's current
// contents (i.e., the <code> element).
// Note that we must set the cell's name explicitely.
inspector.fulfilled(element.value, 'filtered_value');
}
return element;
}
Insert cell
Insert cell
filtered_value * 2
Insert cell
Insert cell
throbber(['wait', 'w a i t', 'w a i t', 'w a i t'], 500, invalidation)
Insert cell
function throbber(steps, delay, invalidation) {
let step = 0, id;
const text = htl.html`<span style="white-space: pre">`;
const animate = () => {
text.textContent = steps[step++ % steps.length];
id = setTimeout(animate, delay);
};
animate();
invalidation.then(() => clearTimeout(id));
return text;
}
Insert cell
Insert cell
function inspectorPrompt(value, options = {}) {
const {
name,
prompt,
empty = value => value == null,
throbberSteps = ['', '.', '..', '...', ' ..', ' .'],
throbberDelay = 350,
invalidated = invalidation
} = options;

const view = html`<div>`;
const inspector = new Inspector(view);
if(!empty(value)) {
inspector.fulfilled(value, name);
view.value = value;
return view;
}

const placeholder = htl.html`<div style="font: var(--monospace-font); padding: 4px 0">
${prompt}
${throbber(throbberSteps, throbberDelay, invalidated)}
`;

view.appendChild(placeholder);
inspector.pending();
return view;
}
Insert cell
Insert cell
viewof text = Inputs.text({submit: true})
Insert cell
viewof processed = inspectorPrompt(text, {
name: 'processed',
prompt: 'Please enter a value above',
empty: value => value == '',
throbberSteps: ['👆', ' 👆', ' 👆', ' 👆'],
})
Insert cell
processed
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more