stage | start-date | release-date | release-versions | teams | prs | project-link | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
accepted |
2025-01-10 00:00:00 UTC |
|
|
This RFC proposes removing ember-fetch
from the blueprint for new projects, and recommends alternative, more native, ways of having "managed fetch".
the package, ember-fetch
, does a fair bit of deceptive and incorrect behavior that is incompatible with modern JavaScript tooling, such as being ember-fetch
, yet only importing from fetch
.
- Remove ember-fetch from all blueprints
- Deprecate the npm package and archieve the github repo.
- Migrate to an alternative for "managed fetch"
primarily, it wraps the native fetch
in waitForPromise
from @ember/test-waiters
(aka "settled state integration").
secondarily, but not popularly used, are a series of utilities (e.g.: for checking kinds of errors). These could be copied into projects that use them and modified to fit each project's needs.
If you only use ember-fetch
in route model-hooks, then the settled-state integration isn't used (or rather, you rely on the routing's settled-state integration, and ember-fetch
's settled-state integration is extraneous)
To replace ember-fetch
's core-functionality using the least amount of effort involves adding a new utility in @ember/test-waiters
, waitForFetch
:
// in @ember/test-waiters
import { waitForPromise } from './wait-for-promise';
export async function waitForFetch<Value>(fetchPromise: Promise<Value>) {
waitForPromise(fetchPromise);
let response = await fetchPromise;
return new Proxy(response, {
get(target, prop, receiver) {
let original = Reflect.get(target, prop, receiver);
if (['json', 'text', 'arrayBuffer', 'blob', 'formData'].includes(prop)) {
return (...args) => {
let parsePromise = original.call(target, ...args);
return waitForPromise(parsePromise);
}
}
return original;
}
});
}
To have a single import mirroring the behavior of ember-fetch
, in full, folks can still provide a single export that does:
import { waitForFetch } from '@ember/test-waiters';
export function wrappedFetch(...args: Parameters<typeof fetch>) {
return waitForFetch(fetch(...args));
}
And then throughout your project, you could find and replace all imports of import fetch from 'ember';
with import { wrappedFetch } from 'app-name/utils/wrapped-fetch';
Potentially an easier-to-manage implementation uses a service such as the following:
import Service from '@ember/service';
import { waitFor } from '@ember/test-waiters';
export default class Fetch extends Service {
@waitFor
@action
requestJson(...args: Parameters<typeof fetch>) {
return fetch(...args).then(response => response.json());
}
@waitFor
@action
requestText(...args: Parameters<typeof fetch>) {
return fetch(...args).then(response => response.text());
}
}
Docs available on https://github.com/emberjs/data/
- Add a deprecation notice to the ember-fetch README
- Archive the ember-fetch repo
- Remove ember-fetch from the blueprints
- Remove ember-fetch from the guides (only one reference per version)
- if we keep ember-fetch is not compatible with modern tooling and modern SSR approaches
- n/a
- ask folks to wrap and proxy fetch themselves
none