Table Of Content
Directive Or Pipe?
Angular provides two ways to work with DOM elements, Directives and Pipes.
Pipes are used to transform data in the template, think of them as formatting tools that refine how your data is displayed. They’re not concerned with the structure of the web page itself; their primary job is to make sure your data looks the way you want it to when it hits the screen.
Directives are used to directly interact with and manipulate the DOM. These can either tweak the characteristics of individual elements (Attribute Directives) or even change the very layout of the DOM by adding or removing elements (Structural Directives).
You’re going to implement Infinity Scroll as Directive and Pipe, and see the pros and cons of each approach.
- Modify the
InfinityScrollOptionsinterface to omit the
elementproperty because you’re going to use the directive’s host element.
noMoreData$property to the
InfinityScrollOptionsinterface, this is a user defined Observable that tells if all data had been loaded.
The good thing about directives is that you can inject the host element without having to explicitly pass it to the directive.
You need to store the data in a buffer, so that you can accumulate it when the user scrolls, and emit it as a single array and to use it you need to expose the directive instance to the host template.
@Input to pass the
InfinityScrollOptions to the directive (you can use InjectionToken if you prefer).
The directive is designed to allow
options to be changed at runtime, so it’s important to unsubscribe from the previous infinity scroll subscription before creating a new one.
scanoperator is used to accumulate the data, and emit it as a single array.
takeUntil, first one, operator is used to stop the infinity scroll when
noMoreData$emits. Second one, is used to stop the infinity scroll when the directive is destroyed.
ngOnDestroy lifecycle hook is used to unsubscribe from the infinity scroll subscription and complete the data buffer.
Nothing complex here, loop over the data source and show a loading indicator. The important part is
overflow styles, they’re used to make the container scrollable, otherwise there will be no scroll event to listen to.
Configure Infinity Scroll
Before configuring the infinity scroll, you need to know when to stop it, it might not be required in your case, but in case you need it, infinty scroll should stop when all data had been loaded otherwise you’d end up making same call over and over again.
The infinity scroll options are pretty much the same as the ones used in the vanilla implementation, the only difference is that you’re using
HttpClient to fetch the data.
- Element reference is available through DI.
- You have to manage the subscription manually.
- You have to unsubscribe from the previous infinity scroll subscription before creating a new one.
- You have to empty the data buffer before creating a new infinity scroll subscription.
The operators used in the pipe are the same as the ones used in the directive.
The difference is with how we are receiving the
elementreference, in the directive we are injecting it, but in the pipe we are receiving it as an argument.
Due to pipes nature, you don’t need to maintain a seperated data buffer, thereby
asyncwill manage the subscription for you.
Use it in a component template
- You don’t have to manage the subscription manually.
- You don’t have to empty the data buffer before creating a new infinity scroll subscription (async will discard the previous data).
- You have to explicitly pass the element reference to the pipe.
I wasn’t able to round my head around how to implement it using signals due to the need to pass element reference, if you have any idea please let me know in the comments.
You’ve discovered how to implement Infinity Scroll in Angular using Directive and Pipe, and saw the pros and cons of each approach. Choose the one that suits your needs. Personally I’d go with the pipe approach, because it’s more declarative.