Intersection observer in JS and Angular

While working in a startup we got an interesting problem to solve Reporting of visibility of advertisements in order to calculate ad revenues.

My senior told me to research the Intersection Observer. After researching for a while I discover amazing concepts of Intersection observer. let’s understand the concept of intersection observer in JS and Angular.

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport*. — According to Mozilla Docs*

According to Mozilla docs this simple and interesting concept clears some of the complex problem definition in real-time world in an easy and intersecting manner.

Lazy-loading of images or other content as a page is scrolled.

Implementing “infinite scrolling” websites, where more and more content is loaded and rendered as you scroll so that the user doesn’t have to flip through pages.

Deciding whether or not to perform tasks or animation processes based on whether or not the user will see the result.

I have discovered the problem in plain JS. We will Explore the concept in plain JS then we will move forward.

Before going to the actual topic first and foremost we have to understand some basic concepts like viewport.

Viewport: simply it is an area or part which is in the view. In web browser terms, it refers to the part of the document you’re viewing which is currently visible in its window

For Explaining let me show the HTML file:

As you can see we have multiple images in the image-container div.

We have to create an intersection observer for this so that if any new image comes in the viewport immediately we get the message.

Let me explain to you One by One

let observer = new IntersectionObserver(callback);
//This line is used to initialize the Intersection Observer.

let callback = (entries, observer) => {// Logic ….};
//callback contains all logic we want to apply as per our requirements like lazy loading, logging the changes, etc.

finally,

const targets = document.querySelectorAll(“img”);

targets.forEach((el) => {observer.observe(el, { threshold: 1 });});

We define the target and apply the intersection observer on it, threshold defines how many targets should be in the viewport in the 0 to 1 range for 70% of targets must have a 0.7 threshold.

I have console.log(“Entry ==> “, entry.target.currentSrc);

JS Output once elements are in Viewport.

Intersection Observer in Angular:

Now let's dive into the more interesting thing, implementing the Intersection observer into angular believe me the way Angular has to handle it is on the next level.

HTML of Angular Intersection Observer

We have this simple HTML created for the Intersection Observer. Just we define a variable name #view into the HTML. Let's Apply to it.

TS of Angular Intersection Observer — declaration

  1. Declare the view with the help of @ViewChildren Query List properties. What does it simply get all the list of the #view element ref into our view variable?

  2. The interesting thing the second part we have to call the ngAfterViewInit() function which is a callback method that is invoked immediately after Angular has completed the initialization of a component’s view. In that lifecycle view, we have run a for each loop on every element present in the view QueryList variable. where we have called our next part which is the intersection observer function present. The most important thing to note here is we have subscribed to it whenever any changes occur we will get a response.

TS of Angular Intersection Observer

First, we get some knowledge of the RxJS functions:
1. MergeMap: It returns the result based on the Observable function which we have applied and returns the resulting merging Observables and emits the results of this merger.

2. Map: A function that returns an Observable that emits the values from the source Observable transformed by the given project function.

3. DistinctUntilChanged: A function that returns an Observable that emits items from the source Observable with distinct values.

Now we will go one by one through the function:
1. intersectionObserver.observe(element.nativeElement) line run on every element, we are running the observe() so we must observe the specific element if it is the viewport.
2. next our const intersection observer is running in which we are emitting or pushing the new value.
3. once the value is pushed mergeMap is running this above function and fetches the results.
4. Map filters only that element that is in the viewport by the entry.isIntersecting if it returns true.
5. We are not returning observable until the change does not happen with help of distictUntilChanged() property of Rxjs.
If the element will is in the viewport then and only then it will return true.

The output of the Intersection Observer in Angular

Reference:

Mozilla docs: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

#WeMakeDevs #fullAnsari