0

I want to make a page where you can see all the users registered to the website. The url for that is /users. When someone goes there, the server searches the database for all the users and returns an array of objects. But I want to make it so that I have more than one pages for that (pagination/ kind of like google and amazon etc.). Page 1, page 2, page 3 and so on. So, I splice() the array of objects returned by the previous function. When I console.log() it the array seems to be ok, but when I got the /users page it says it can't find the array (but the array is normally passed to the client). When I don't have the splice method, it works ok, but I still want to have the pagination. Here's the code:

app.get('/users', function(req, res, next){
var usersArray = [];
  Users.find({}, function(err, users){
    if(err) throw err;
    if(users) usersArray = users; // this works ok
    if(!users) res.send('Found no users!');
  })
usersArray.splice(10, usersArray.length); // for the first page, and only show them 10 users
// I haven't written the code for the second page yet, since this doens't work
res.render('users.ejs', {
  usersArray: usersArray // it gets passed normally
})
}

The client renders the array in some styled html with ejs. The problem is userData not found, on line .....

The user schema is like this:

var userSchema = mongoose.Schema({
  userData: {
    (and all the data about them in here)
  }
});

Again, it works ok, as long as I don't splice the returned array! Any help? Thank you.

Jim The Greek
  • 31
  • 2
  • 7
  • You can use Express-paginate middleware for this. I havent used splice before so cant say much. But express-paginate is really awesome. https://github.com/expressjs/express-paginate. It is very well documented with an example very similar to what you need. – Nischay Malhan Jan 01 '16 at 12:53
  • @NischayMalhan I'll check it out. Thank you! – Jim The Greek Jan 01 '16 at 13:00
  • Couldn't find a flaw on the call to splice() either, but I would suggest using slice instead: `usersArray=usersArray.slice(0,10)` – E_net4 Jan 01 '16 at 13:00
  • @E_net4 Isn't slice for strings only? – Jim The Greek Jan 01 '16 at 13:09
  • Not at all, it works fine with arrays. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice – E_net4 Jan 01 '16 at 13:10
  • @jimthegreek From the docs it says : 'An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned.' and thus I think you need only first 10 elements and not the deleted ones? So slice would be the function to go with – SKY Jan 01 '16 at 13:30
  • @SKY The program wasn't keeping the returned array – E_net4 Jan 01 '16 at 13:40
  • @SKY Nah, sorry. Slice doesn't work either. I'll try the express-paginate middlewere NischayMalhan suggested! – Jim The Greek Jan 01 '16 at 13:46
  • Oh shoot. A second look, and found your issue: the array assignment is asynchronous! You need to render only once you retrieve the users. – E_net4 Jan 01 '16 at 17:45

1 Answers1

0

The database operation find is asynchronous, meaning that the assignment to usersArray will not take place before the splicing and the render. You would always be dealing with an empty array.

To solve the problem, simply move the render (as well as the array slicing) to the callback of your database operation. Also see another answer to a similar issue. It is important that all JavaScript developers understand the concept of asynchronous function calls in this environment.

Community
  • 1
  • 1
E_net4
  • 27,810
  • 13
  • 101
  • 139