As I was researching that Chrome 52 bug yesterday, my friend Smotko showed me something cool: fetch()
.
It’s a native JavaScript function for AJAX GET requests. I don’t know what stage it is, but Chrome, Edge, Firefox, and Opera all support it. Safari doesn’t. Nor do any default mobile browsers, only Android Chrome.
You can use this Babel fetch polyfill to bridge the gap. I wonder if that’s good enough to convince our CTO to let me use this. ?
Then again, why? Oh yeah, that strange Chrome 52 bug doesn’t happen and all I’d have to do was change that one API wrapper function that we use for everything … and thus change our whole codebase … and wreak havoc. ?
But The Bug doesn’t happen! Let me show you.
Ugh, promises don’t work in the console. That’s a bummer … never did like promises. It’s really just weird syntax sugar for callbacks.
fetch("bla.json").then((response) => {
console.log(response.ok); // prints true
console.log(response.body); // ReadableStream O.o
});
fetch()
issues an AJAX request to the server. When it’s done, it triggers the then
part of its promise and gives it a response
object. This object can do many useful things, one of which is to tell you if it was successful. Another is to give you a ReadableStream.
You probably don’t care about readable streams, so there are functions to parse JSON or get raw text. We’re in the brave new world of promises, so those are promises too.
They work like this:
fetch("bla.json").then((response) => {
response.json().then((json) => console.log(json)); // Object {id: 1, hai: "hello"}
response.text().then((text) => console.log(text)); // nothing
});
The json().then()
combination prints a JavaScript object parsed from our data. Which feels roundabout, but the internet tells me that promises are better than The Callback Hell.
This:
fetch(url).then((data) => data.body.json().then((real_data) => doStuff));
Is supposed to be better than:
request.get("bla.json").end((err, res) => console.log(res.body));
¯_(ツ)_/¯
But lets get back to the story: You can’t read the fetch response body twice. See that .text()
call? That throws an error saying that oh hey, the body has already been read, so you can’t do it again.
Maybe there’s no good reason you’d want to do that, but what if I do want to?
There’s an even worse caveat, though. Let me show you what happens when your fetch()
call returns a 404.
fetch("nope.json")
.catch(() => console.log("something went wrong")) // no error
.then((res) => console.log(res.ok)); // but not okay either
With promises, catch()
should give us a chance to catch errors. This keeps our code cleaner because then()
can focus on the happy path.
Somebody decided a 404 error is not a good enough reason to reject the promise. You still have to put a lot of error handling into your happy path.
?
But The Bug doesn’t happen! I tried. You can repeat the same request in the then()
callback and its then()
callback works just fine.
There is an official explanation for how the bug happens in the bug report from 8 days ago. A fix also exists, but it’s not merged yet.
This debacle makes me wish I was braver when first seeing this behavior 3 months ago. Way back when it was Chrome Canary and I thought surely someone would fix it.
What a strange ride it’s been.
Continue reading about JavaScript can fetch() now and it's not THAT great
Semantically similar articles hand-picked by GPT-4
- JS object optimization bug in Chrome 52
- I broke AJAX in Chrome 52 ?
- How to waste hours of life with fetch() and a bit of brainfart
- A tiny ES6 fetch() wrapper that makes your life easier
- Mocking and testing fetch requests with Jest
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️