Adding to composable using a Layer
What would be the best way to add to a composable using layers?
For example, I have my base layer with
/composables/useXY.ts
which has for example:
and I'd like to extend this composable's functionality with another method. I'd like to use layers to do this. If I define this same composable with just the added method in another layer, it just overrides the original one:
What would be the correct way to do this? The final composable should look like:
16 Replies
Is there a reason why the base layer can’t have the final version of the composable?
PS: layers don’t merge conflicting elements. One overrides the other
The reason is that there would be multiple layers that would add different functionalities depending on the layer's needs, but the core functionality should be there. I don't want to duplicate the core functionality to each layer. I'll give you an example
layers/tenant1/
layers/tenant2/
layers/tenant3/
layers/base/
...
where the app is basically made to be multi tenant/version. There are different developers working on this and I would like to force this composable to have a certain basic structure. I know I could create a type definition for the composable and extend it in each layer, but is there any way to force the composable to have a type in each layer without importing the type each time?
The only way I see this being possible now is splitting the composable to multiple composables or the type way which I wrote above.
You can create a configurable composable in the base layer, so that whoever is consuming it can pick which features to use and which to drop. Picture it as a component
how do you mean a configurable composable?
let's say layer/tenant2 needs to implement the delete property inside the composable in a different way than the base layer has it implemented, how would you do that?
I’d have to know what tenant2 is doing differently that can’t be covered by the base layer
transforming the request in a different way, calling another endpoint in the same function, can be whatever
so much so that you don't want to cover 10 different cases in the base layer if you have 10 tenants
another way i could do this is just splitting each method inside the composable into it's own composable
usePost
useGet
useDelete
etc
so then the next layer can override each
but i was thinking if there's a better way than that
Sure, then your composable can simply house all the defaults such that when a tenant imports to use it, the tenant can override parts of it to suit its needs
So you just have to decide when and where the base composable needs to encapsulate what and where the consumer needs to take up the rest of the work
the problem i have with this is that the composable has to be defined then in each layer
and the layer's author might forget to import some methods that should be there by default
That’s going to happen if you don’t make those methods required by the base composable
This is an example of how a tab and tab item component group works. You wouldn’t be able to fully create views in a tab if you don’t include the tab items
Documenting what’s needed where and when for the tenants would also help
hmm do you see any way of enforcing a type on a composable with the same name as the composable in the base layer without having to import the type manually?
as in "each function in composables named XYZ should have this type"
there's also one more problem i noticed. if there's a composable
useX.ts
in layer A that's defined as
and we override get.ts
in layer B
layer B's get.ts
doesn't override layer A's get.ts
- it doesn't seem to include themMmm not sure how that would work if there’s no single source of truth.
Here’s my suggestion: when creating the compsable under a tenant, let the tenant name it differently from that of the base layer. Eg;
hmmm but then they're not switchable
Is layer B extending layer A?
Meaning?
meaning if you have a page/component/layout using
useSomeComposable
you have to replace it with the one that overrides it everywhere
yes layer B is extending layer AThat depends on whether the layout is okay with how the base layer’s composable functions for its sole use case as against the customized version in the tenant. Otherwise, yes
If you want to have a customized/extended
useFetch
composable for instance, you’d need to export it under a different name with the necessary customizations
Take note that the consumer always takes the highest precedence, so if there’re name conflicts the base will be overlooked in favor of the consumer/tenantyeah, the idea is to keep the naming of composables the same so that another layer just overrides/adds on top and there's no need to change anything in the consumer's code