Importing

default vs named imports

If the library uses a default export, you will need to unwrap it:

https://www.val.town/embed/stevekrouse.npmDefaultExample

You’ll often notice that you need to do this if you don’t do it and get an unhelpful error:

https://www.val.town/embed/stevekrouse.npmDefaultErrorExample

This isn’t necessary for libraries that use named exports. There’s even a version of lodash that does this:

https://www.val.town/embed/@stevekrouse.npmExample

Rendering

Vals don’t support outputting a UI, such as HTML or JSX.

The most common pattern is to use our HTTP Val to output HTML:

https://www.val.town/embed/neverstew.webHTMLExample

You can easily import any val into a frontend via the API. Like in this example in Observable.

Uncaught Async Errors (Unhandled Promise Rejections)

If you don't await or .catch a Promise, any potential errors it throws will not be associated with your val and you won't be notified of it.

// ✅ errors & emails you
try { await fetch("hi") }
catch (e) { console.email(e) }

// ⛔ fails silently
(() => { fetch("hi") })()

// ✅ error in UI
// val town awaits top level Promises 
fetch("hi")

Unexpected Empty objects: {}

In many cases, if you’re getting an empty object {} where you don’t expect one to be, it might be that Promise that wasn’t awaited. If you get an empty object, try awaiting it and see if that solves the problem. It could also be due to how we only persist JSON data.

setTimeout