FSIBLOG

JavaScript Why Am I Getting a Content Promise Instead of Text

JavaScript Why Am I Getting a ContentPromise Instead of Text

TL;DR You forgot a second await. Body reading methods like .text() and .json() are async. Always await them.

The Bug in One Line

const text = response.text(); // Returns a Promise, not text

How to Spot It at a Glance

If you console.log() a value and see any of the following, a missing await is almost always the culprit:

Promise {<pending>}
Promise {<fulfilled>: undefined}

[object Promise]

Key Takeaway

fetch() gives you a Response. .text() and .json() give you the body but only after a second await.

Two async steps. Two awaits. Every time.

What Actually Happen

When you fetch() a URL, JavaScript resolves the request in two stages:

  1. The HTTP response headers arrive → await fetch(url) resolves.
  2. The response body streams in → await response.text() resolves.

Most developers await stage 1 but forget stage 2. The result? You’re holding a Promise {<pending>} object and wondering why your string looks like an object.

The Fix

// Before - missing the second await
const response = await fetch('https://api.example.com/data');
const text = response.text();
console.log(text); // Promise {<pending>}

// After - both stages awaited
const response = await fetch('https://api.example.com/data');
const text = await response.text();
console.log(text); // "Hello, world!"

It Affect All Body Methods

This isn’t just a .text() problem. Every body-reading method on a Response object is async:

MethodReturns
response.text()Promise<string>
response.json()Promise<any>
response.blob()Promise<Blob>
response.arrayBuffer()Promise<ArrayBuffer>
response.formData()Promise<FormData>

Rule of thumb: If it’s on a Response object, it needs an await.

Valid Pattern

// Pattern 1: Two lines, two awaits (most readable)
const response = await fetch(url);
const data = await response.json();

// Pattern 2: One-liner (compact, slightly harder to debug)
const data = await (await fetch(url)).json();

// Pattern 3: Error handling with try/catch (production-ready)
try {
  const response = await fetch(url);
  if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
  const data = await response.json();
  console.log(data);
} catch (err) {
  console.error('Fetch failed:', err);
}

How to Spot This Bug Fast

If you ever console.log() a value and see any of these, a missing await is almost always the culprit:

Tools to Catch This Bug Early

Don’t wait until runtime to discover a missing await. These tools will flag it instantly:

ToolHow it helps
VS CodeYellow squiggly underline on un-awaited Promises
ESLintno-floating-promises rule catches it at lint time
TypeScriptStrict mode throws a type error Promise<string>string
Chrome / Firefox DevToolsConsole prints Promise {<pending>} the clearest visual clue
Vitest / JestAsync tests fail when you accidentally assert a Promise object
PrettierConsistent formatting makes missing awaits easier to spot visually

Fastest setup: Enable TypeScript strict mode + ESLint together they catch this error before you even run the code.

Exit mobile version