Too much junk in your Angular components? Try composition instead of inheritance!

preview_player
Показать описание

In this video, we take a look at how to keep your components DRY (Don't Repeat Yourself) by using both an inheritance pattern and a composition pattern with services.

Source code:

More resources:

0:00 Introduction
1:49 Inheritance
4:08 Composition vs Inheritance
5:13 Composition
9:34 Conclusion

#angular #ionic #architecture

Рекомендации по теме
Комментарии
Автор

This just moves inheritance to services. Take a look on the decorator pattern, it will also let you use lifecycles.

chriskrezias
Автор

So i adopted Angular from day 1 and yet your videos make me learn new things every time.

Автор

In real life app, if you have single data model, it can be like a: one component and one service and pass api url through navigation; two components one service (component process some data for api call); and so on... Main angular principles are KISS and TDRY. So may be you will do part 2.

AKalinskiy
Автор

Sorry but this is not even close to a composition. It's the same inheritance but with extra step of moving inheritance part into service. It doesn't give you benefits of composition and keeps all the downsides of inheritance, also now that you extend services you can't use things like angular decorators and component lifecycle methods. With composition you could compose out of many elements independently, but in this case you are still limited by 1 inheritance chain for your services, since you can't extend more than 1 class
What is the point of `{ provide: AbstractListPageService, useClass: ProductsService }`? You say that if you wanted you could easily swap ProductsService into something else, but you could still do that if you defined constructor as `constructor(public listPage: ProductsService)`, you would just be swapping your implementation service in constructor instead of in prodivers array. Since ProductsService extends AbstractListPageService it's just the same thing anyway? Your providers array is still statically defined in the same file, it's inseparable from your class, it's not dynamic. You could do the same thing also by injecting listPage as ProductsService but referring to it as to AbstractListPageService (e.g. saving to a class field of type AbstractListPageService) - it doesn't make a difference

maxk
Автор

@josh, you are amazing. Your explanation and videos are so clear that I even can follow them. Thank you.

alexle
Автор

Hi,
I know it‘s already 6 month, but I just watched you video and see one downside. I believe one very important downside (or at least good to know think) is, that you don‘t habe a singleton anymore in a way that the services keeps living after you left the page. Providing a service directly in the component is good if you want to separate the logic from the component. But if you want to yous caching for example you have to provide a service in root. (Correct me if I‘m wrong)

E.g. I have a search field with categories, I don‘t want to retrieve the categories everytime from the backend.

NicoTasche
Автор

To me, this still looks like inheritance with some small sprinkles of composition.

Chris-jmgx
Автор

divide and conquer? Indeed, it's a smart approach.

kamertonaudiophileplayer
Автор

Great Explanation man!

Does this means that service class is behaving like a component's typescript class?

ilirbeqiri
Автор

If you use an abstract class and a base class, would it be better to have the repeated code in the abstract class directly? An abstract class can have actual code not only abstract methods

Iam_AndersonP
Автор

This is nice, but I still would prefer Inheritance. I don't like complicated things and inheritance is like a plug and play for me.

lancetv
Автор

I think it's the bridge pattern. Not really composition.

nicksunny
Автор

Thank you for this video, amazing explanation! I'd love to implement this logic to bring order to my components. However, I often have scenarios where I have duplicate logic in different components, but where that logic uses functions / variables which are part of a different system of logic of the component. Would there any way to still use composition or inheritance in that case?

ArchiRuban
Автор

Hello Joshua.. i really like your video and the content ! Great job =) He trigger me every time but.. you use ngIf="{data: data$ | async, ...}" but with this approch you loose the benefit of the ngIf because you pass an object. Why dont use rxjs with combinaLatest to create a array and pass in ngIf ? thx

Fyasco_AlanChoufa
Автор

9:10 couldn't you just have placed the content of ListPageService inside AbstractListPageService?
You would have had an AbstractListPageService with common logic, that is reusable and extendable.
I assume there's nothing wrong about having some logic inside abstract classes, in fact, there are examples of this in typescript official manuals.

TheSome
Автор

Can we call it Foster Parent-Adopted Child inheritance?

aravindmuthu
Автор

Excellent! Could this commonly needed abstraction be put into an OSS package installable with npm? I would even love to see a great library of these types of abstracts in one npm package.

ToddHale
Автор

this isn't true composition though

lautrec
Автор

Your example is not actually composition ... it's still inheritance just moved the inheritance to the service. Composition would be MyComponent extends where all the logic within AComponent and BComponent is made available in MyComponent (or service).

giorgosgernas
Автор

I'm sorry, but all what I see now is that our "inheriting" was just moved from components level on services level.
Of course it's better than base component inheritance, but it seems it will be better to move all that listSearch$ and data fetching logic into some wrapper component and just provides particular service from Employee and Products component to that wrapper.
** And that wrapper additional will solve problem with employee-list.component.html and products-list.component.html duplicating

Please clarify that moment because I'm a little bit confused :)

But anyway - thanks for your time!

vandervise