-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intent to deprecate: The class-based Resource. #1056
Comments
An extracted package that supports the class-based Resource API would be useful as a migration step Could be similar to 🤔 I guess if that boilerplate is small enough it might be easier just to keep locally |
@NullVoxPopuli pardon my ignorance, what is the way to lookup a service in a non class-based resource? e.g. we have some resources that abstract complex data fetching so we write reactive code in a template and make resource lifecycle bound host component. how could you e.g. inject |
Function-based resources have access to the @use myData = resource(({ on, owner }) => {
const store = owner.lookup('service:store');
on.cleanup = () => {};
}); |
In this case, it would be nice to have a codemode to switch to Native classes avoiding modify. I'm a little bit addicted to class resources as an encapsulation of some context. |
@NullVoxPopuli Hi, thanks for the post. I think this can be a very good move. TBH, I have been struggling quite a lot in understanding the concepts of resources. It has felt like the transition to Octane provided an elegant simplification in DX and mental model, whereas my attempts of using resources hasn't really gotten into my fingers yet. In retrospect, perhaps some of my confusion has been due to the unclear concerns ("teachability") regarding mix-up of function-based and Class based resources. |
Personally, I like the readability of injecting services using decorators. Using owner.lookup is a code smell imo. |
I think I want to extend the import { resource } from 'ember-resources';
import { link } from 'ember-resources/link';
class DisplayRepo {
constructor(private _socket: () => WebSocket) {};
@cached
get socket() {
return this._socket();
}
@service declare store: StoreService;
@service declare intl: IntlService;
doTheCleanup = () => { ... };
// etc
}
function GetData(socket: () => WebSocket) {
return resource((r) => {
let instance = new DisplayRepo(socket);
link(instance, r);
r.on.cleanup(() => instance.doTheCleanup());
return instance;
});
} What are folks thoughts on this? (or something similar) The main thing is that you don't lose the ability to use plain classes in ember (that's worked for ages!), but there should probably be an ergonomic way to wire them up. |
@NullVoxPopuli as above is just set of functions, how |
Same way it does today, via
It doesn't need to, because it comes from the call-site waaaaaay down in helper-manager land. We have the owner here, in the manager for function-based resources, and we'd do |
@gilest, yes, this is a great idea -- it's all still built on public API, and can be supported on that public API from 3.28+
@mabab I (or someone!) could give that a go |
I've added this issue to the v7 plan quest issue: #1061 lemme know what you think! |
Note
this is the second topic of deprecation in planning for ember-resources@v7. The other set of things to look at is over here: #1046
Looking for feedback here before following through with this deprecation, as I know some big players are using class-based resources -- but in part because the existed before the current design of resources existed.
There a few related motivations:
modify
hook. This was, in a way, used as a backdoor to implementing effects, which, in performant codebases, have niche use case.Specifically, as a migration path, focusing on "The spirit of class-based resources can be implemented in userland" can be done in a couple of ways.
Note
These examples are highly dependent on your use case. If you have a use case that's not covered year, please comment!
having a value update when args change (part 1)
The way to do this yourself:
the
doubler
classic helper would be what is invoked now instead of the oldDoubler
.classic helpers are already usable in templates, and using them in JS can be done with the
helper
util, which reduces the boilerplate overinvokeHelper
.This technique allows you to keep all your public API the same, but implementation can be way simpler if you're in a place to change all the public API / how the args are passed in.
For example, if you only used your resource in JavaScript, you may not need a resource:
If you either:
make a class for your args object
or make all your args arrows, you can do this:
Uses link
(note that link is an abstraction over some framework wiring that can get verbose -- it's not "needed", but the alternative is verbose)
How do you use
resource
to wire up a native class?The old behavior didn't receive the args in the constructor, as it followed the ember-modifier pattern of only having a
modify
hook.To get the spirit of that behavior back, you may want something like this:
Caution
this is a side-effect, and side-effects often cause infinite revalidation situation and should be avoided.
A hack around this is to use an async IIFE or async function, but it's unergonomic, and relies on timing happenstance with the reactivity system and rendering.
(noting that nothing
await
smodify
)or
or
Native classes and avoiding
modify
The text was updated successfully, but these errors were encountered: