Paging in getMovies()

const displayCursor = cursor.limit(moviesPerPage).skip(page)

i am getting the 20 movies/page by scrolling but the test didn’t pass saying
Test Suites: 1 failed, 1 total
Tests: 3 failed, 3 total

1 Like

I am confused about this ticket:Paging. Can someone give me a hint.

Am I supposed to update the const displayCursor = …
and add a “for” loop inside the try…catch block ?

The “hint” is that paging here is done the same way it has been done in all database queries for many many years. This should be very easy to look up in many sources on the internet.

Basic Concepts

  1. You have the number of items you want to show on a page i.e moviesPerPage

  2. You have a page which you want to display, which means you want to skip over the number of items per page multiplied by the previous pages ( x items per page remember ) and then limit to the number of items per page.

  3. 0 multiplied by a number is 0

That should be more than enough to reason an answer from.

14 Likes

Got it ! Thanks a lot @neillunn

Is getMovies called every time a new page shall be viewed?
How do I keep track of what page the user are at?

. . . Also I do not undestand the line:

const totalNumMovies = page === 0 ? await movies.countDocuments(query) : 0

The UI is sending back the page it wants. Every time you scroll down and reach a certain threshold, the UI will send a request for the next page. All you have to do is ensure the math works out in your return so that you skip the documents already found and limit to return only the next usable portion of documents.

Incidentally, this is not the best way to do paging in MongoDB, but we wanted to introduce the idea of it.

1 Like

Thanks @neillunn.

I was initially writing my own query. I am glad you help clarify the question a bit more.

Broken apart, the line can be read as:

the constant totalNumMovies equals if page is strictly equal to 0 the result of counting the number of documents in the movies collection that match the supplied query, else 0

This is a ternary or conditional operator in Javascript.

So true.

But of course the implemented test from the status page used for the question assessment requires this is the method used.

I guess a search for Forward/Fast Paging with MongoDB should point to some descriptions of how to do this “better” in cases where absolute page number references are not required, and avoiding “skipping a cursor” is possible.

Correct. However, this is our entry level developer course so we wanted to make the implementation as straightforward as possible.

I think I got it (at least my test passed :slight_smile: )
However I’m confused by the handling of the Cursor. If I understand correct the UI is using the Cursor to display a page. What I do not understand is how the UI is doing that. It can not be by calling getMovies for every page it wants right?

1 Like

I got paging to work but it always follows the true part where page equals zero. I don’t understand why it is used.

The UI should be sending the page back so subsequent requests should be non-zero. This is done because asking for a second or nth page requires the same query, so no need to recalculate the number of documents in total that would be returned by the query.

Thanks a lot, @neillunn !

I do not quite understand how the parameters work inside this function.

static async getMovies ( { filters = null, page = 0, moviesPerPage = 20 } = {} ) { 
   ...
}

Here’s my understanding. First I understand it as: 3 parameters are defined for this function getMovies and assigned an initial value. But what I don’t get is why this object { filters, page, moviesPerPage } is then assigned an empty object {}. Why assigned values initially when the next step is to make it empty?

I am expecting it to be more like:
static async getMovies ( { filters = null, page = 0, moviesPerPage = 20 } ) { ... }

Please help / correct if I am wrong.

Well basically your expectation is correct, as the = {} as a default when there are no parameters is overkill when you already defined defaults for all parameters.

As a little more expansion, there are quite a few “faux pas” present in the code. Largely present in async/await overusage i.e:

return await somePromise()    // basically a useless and ignored await

And mostly various other things which would lead me to think the main developer would be more fluent in Java than JavaScript i.e:

String(e)   // Where e is an Error Object, so the rest of the world does 
                 // e.message rather than type coercion

And various other ugly things, too numerous to list.

Basically, you need not care for these and really should be learning “coding style” from other sources than this course material.

Just use this course as an “introduction” into where you apply the NodeJS driver methods in interaction with MongoDB for various types of things with CRUD, Aggregation. And really only care about the parts of code you are specifically asked to edit.

@CARLOS_64548 Please see: Database imported by the project is not the same as the course

Do Not Change Test Cases as they are all correct. If anything, verify your data as is described in that post.

2 Likes

520/5000
@rohit114
Look at this number is correct with Compass or MongoShell , in my case, in reality, 31675 in the test, like 31680.


paging.test.js
// check the total number of movies, including both pages
expect (totalNumMovies) .toEqual (31675)


moviesDAO.js
// ALL Ticket: Page
// Use the cursor to return only the movies that belong to the current page

const displayCursor = cursor
.limit (moviesPerPage)
.skip (moviesPerPage * page )

I hope it helps

follow me on GitHub: https://github.com/CarlosGutierrez1989/mflix/commit/a11395275e25c5af157695a635a6b13f657da13f

2 Likes

What trow me off was line 281

const totalNumMovies = page === 0 ? await movies.countDocuments(query) : 0;

@neillunn

Great tip :smiley: