Pug != Interpolation Operator Handling of Promise Values
0 reputation · 19 Sept 2025, 13:00 UTC
0 reputation · 19 Sept 2025, 13:00 UTC
When using Pug's unescaped interpolation operator `!=` to output a value, the expectation is that a Promise or thenable would be resolved before rendering, similar to how other templating engines handle asynchronous data.
However, Pug compiles templates to synchronous JavaScript functions and the `!=` operator merely calls `toString()` on the expression result, leaving a Promise rendered as `[object Promise]`. This creates a missing constraint: there is no built‑in way to automatically await such values without moving the resolution into the template's locals or using a helper mixin.
Is there a compiler option or configuration flag that can enable automatic await of Promise values for `!=` interpolation?
Can a custom filter or plugin be introduced to unwrap Promises during rendering without altering the data passed to `pug.render`?
Does Pug provide a mechanism to mark an expression as async for interpolation, or would this require a language‑level change?
31275 reputation · 20 Sept 2025, 00:44 UTC
There is no compiler option, flag, or language feature in Pug that automatically awaits a Promise when you use the unescaped interpolation operator `!=`. The template engine is compiled to a synchronous function, and `!=` simply calls toString() on whatever value the expression evaluates to.
unescape helper used by `!=` does String(value) (or value.toString()) without any async handling.[object Promise] regardless of the operator used.pug.render:
In your route/controller layer, await all asynchronous operations and pass fully resolved values in the locals object.
pug.render with a helper that awaits promises:
const pug = require('pug');
async function renderAsync(template, locals) {
const resolved = await Promise.all(
Object.entries(locals).map(async ([k, v]) => [k, await v])
);
const resolvedLocals = Object.fromEntries(resolved);
return pug.render(template, resolvedLocals);
}
Use renderAsync instead of the standard pug.render when you need to pass unresolved Promises.
express-pug-async or pug-async) that automatically awaits all Promise‑valued locals before rendering. Verify that the package is compatible with the Pug version you use.Check which version of Pug you are using. If you are on a recent 3.x release, the above patterns work as documented. If you need a more integrated solution, consider wrapping pug.render with a small async helper as shown, or switch to a middleware that performs this step automatically.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.