Pagination using React and Mongodb

ref – https://www.freecodecamp.org/news/reveal-on-scroll-in-react-using-the-intersection-observer-api/

HomePage

We have a HomePage that calls getAllPhotos for the initial data retrieval.
We get the photos and next_cursor, but they are not rendered. Rather, we let a child component PageOne render these data.

notice here getAllPhotos’s parameter is empty.

But first, let us analyze getAllPhotos and how it retrieves data.

getAllPhotos

The function has a parameter searchParams. The searchParams indicates what next is. Next is the initial element that we are starting at when we grab the next ten elements from mongodb.

On the 1st pass, next is null because in HomePage getAllPhotos was called with empty param.

Which means if next exists do this:

if next is null (which it is here on the 1st pass) then we just use { $exists: true }, which means we match documents that contains the field ‘_id’.

Therefore, on the 1st pass, PhotosoModel model would return ten documents in mongodb.

Then we look at the 9th doc. We get the id for it. This is so that we know the location of where to start grabbing data for the next time around. If next_cursor is null, then we are done.

We return the next_cursor so that child rendering components know how to proceed like so:

So now, let’s take a look at how PageOne rendering comonent processes this:

PageOne

This is a component that renders data.

First thing’s first. Let’s save the param data to state.

Its basically renders photos like this:

In Inspect window, you will see that we are observing a reference’s current to see if its true or false.

So let me explain why.

Observing when a button appears in our ViewPort

First, we need to create a custom hook. Hooks are reusable functions.

We need to implement a useInView in order to put it in our PageOne and observe if a button appears in our viewport.

In order to do this, we create a reference and point it to the button.

So we first create a custom hook.

As you can see, we use a useRef to persist value of a button between renders. It can be used to store a mutable value that does not cause a re-render when updated.

Specifically, we return the ref from useInView and store a button in it:

We reference this button because we need to observe the ref’s current property. ref’s current is now button.btn_loadmore

Then create an observer and observe ref.current.

We use an IntersectionObserver to observe for if our button has appeared in our viewport. In other words, the Intersection Observer API allows you to configure a callback that is called when a target element intersects either the device’s viewport or a specified element. That specified element is called the root element or root for the purposes of the Intersection Observer API.

So in our case, our useInView custom hook observes to see if the referenced button has appeared on our viewport. If it has, then it update inView state in our custom hook useInView.

This variable (inView) is being monitored by useEffect in PageOne, and when it changes to a ‘true’, we would load more data. (as shown in the image above)

If it changes to a false (when the button is not in viewport), then inView is false, and the evaluation would in PageOne would see that inView is false, we don’t do anything.

So in other words, inView is returned from custom hook useInView. When we have not scrolled down to make button appear in viewport, isIntersecting is ‘false’. So we don’t load more.

When we’ve scrolled so that the button appears in viewport, IntersectionObserver’s entries[0] isIntersecting is true. So we would call this function handleLoadMore().

2nd Pass

Now we have to ask ourselves, so the BUTTON appears and we handleLoadMore. But what is handleLoadMore ?

It stops loading if next becomes null, or is loading. It locks the function from being called multiple times by setLoading to true.
That way, other calls will return.

Then it goes and getAllPost with the marker next (which should be fef)

when getAllPhotos returns, next_cursor has gone down the next 10 items ($lt: next) and put it in photos. next_cursor has been updated to the next 9th element.

But this time around since next !== null, we run:

We’re sorting by sort ‘-_id’ so it comes to $lt: next, which means get less than from the next initial marker.

We keep scrolling down to make the button appear, which will do more loading data, until we come to the end. The end is where when we grab the last few items in our mongdo that is less than 10. At that point next is null, and we don’t load anymore.

Future (perfect)

ref – https://www.natterandramble.co.uk/future-perfect-tense-timeline-form-uses/

The Future Perfect tense expresses action in the future before another action in the future.

Future perfect framework:
[will] + [have] + [past participle]

If you see a subordinate conjunction + simple present, we use future perfect.

  • by
  • before
  • at
  • when

Future Simple: “What will happen?” (Focus on the future action)

Future Perfect: “What will have been completed?” (Focus on the completion of the action by a future time)

(present)——— I left ——— you read this ———(future)

How to Form a Future Perfect Example Practice

ex:

1) [before] they arrive. (sub conj + present simple tense)
2) I will have returned. (future perfect)

I will have returned before they arrive.

(present)——— I return ——— they arrive ———(future)

ex:

1) Alice will have returned home. (future perfect)
2) [when] the store closes. (sub conj + present simple tense)

Alice will have returned home when the store closes.

(present)——— Alice returns home ——— store closes ——— (future)

ex:
1) [Next] July starts (subj conj + present simple tense)
2) We will have received our degree. (future perfect)

By next July, we will have received our degree.

ex:
1) [By] next summer (subj conj + present simple tense)
2) We will have built the bridge.

By next summer, we will have built the bridge.

ex:
1) [when] they arrive. (subj conj + present simple tense)
2) We will have eaten.
We will have eaten when they arrive.

ex:
1) I will have eaten. (future perfect)
2) [before] the party starts. (subj conj + present simple tense)

Before the party starts, I will have eaten.
I will have eaten before the part starts.

ex:
1) [when] The click strikes twelve. (subj conj + present simple tense)
2) We will have perished. (future perfect)

The soldiers will have perished when the clock strikes twelve.

ex:
1) [at] ten o’clock (subj conj + present simple tense)
2) I will have finished showering (future perfect)

I will have finished showering at ten o’clock.

(present)——— finish shower ——— ten o’clock ——— (future)

How to Identify

  • Future Simple: “What will happen?” (Focus on the future action)
  • Future Perfect: “What will have been completed?” (Focus on the completion of the action by a future time)

They (build)____________ a new school by next year.
(completion of building a new school, so use Future Perfect ‘will have built’)

If you leave now, you (miss) ______________ the bus.
(future action of missing the bus, so Future Simple ‘will miss)

By the time he gets here, the movie (start) __________________.
It indicates that one action (the movie starting) will be completed before another future action (his arrival), so use Future Perfect ‘will have started’)

By this time next week, we (be) ________________ on vacation. (future action of being on vacation, so Future Simple ‘will be’)

In a few years, technology (change) ____________drastically.
(completion of technological change, so Future Perfect ‘will have changed’)

By the end of the year, I (read) ___________________ fifty books.
(completion reading 50 books, Future Perfect so “will have read”)