Vue Asynchronous Computed Getter

ID

javascript.vue_async_in_computed

Severity

high

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Reliability

Language

JavaScript

Tags

async, reliability, vue

Description

Reports a Vue computed getter that starts asynchronous work: an async getter, an await, a .then continuation or a fetch.

Only the getter is judged. A setter may do whatever a method may do, and a method or a watcher is exactly where the asynchronous work belongs.

Rationale

// Bad — the property holds a Promise
const user = computed(async () => {
  const response = await fetch('/user/' + id.value);
  return response.json();
});
  • A computed property holds what its getter returns, and an asynchronous getter returns a Promise. The template renders [object Promise] where the value was meant to be, or nothing at all, and no error anywhere — the getter did return something.

  • The dependency tracking fails too, and less visibly. Vue records the reactive values a getter reads while it runs; anything read after the first await is read on a later tick, when tracking is no longer active. The property stops re-evaluating and looks stale rather than broken.

  • The getter has no schedule of its own: Vue re-runs it whenever a dependency changes, so an HTTP request in a getter is one request per invalidation, at a rate the component does not control.

Remediation

Load in a watcher or a method, keep the result in state, and let the computed property derive from that state.

// Good
const user = ref(null);

watch(id, async (value) => {
  const response = await fetch('/user/' + value);
  user.value = await response.json();
}, { immediate: true });

const displayName = computed(() => user.value?.name ?? 'unknown');

© 2026 Xygeni. All rights reserved