web-dev-qa-db-fra.com

Comment puis-je transmettre des variables Express.js aux fonctions MongoDB?

Je travaille sur une application de blog (cliquez sur le lien pour voir le GitHub repo) avec Express , EJS et MongoDB.

J'ai fait un simple pager pour les messages.

Dans les messages contrôleur j'ai:

exports.getPosts = async (req, res, next) => {

  const posts = await Post.find({}, (err, posts) => {

      const perPage = 10;

      const currPage = req.query.page ? parseInt(req.query.page) : 1;

      const postsCount = posts.length;

      const pageCount = Math.ceil(postsCount / perPage);

      const pageDecrement = currPage > 1 ? 1 : 0;

      const pageIncrement = currPage < pageCount ? 1 : 0;

      if (err) {
        console.log("Error: ", err);
      } else {
        res.render("default/index", {
          moment: moment,
          layout: "default/layout",
          website_name: "MEAN Blog",
          page_heading: "XPress News",
          page_subheading: "A MEAN Stack Blogging Application",
          currPage: currPage,
          pageDecrement: pageDecrement,
          pageIncrement: pageIncrement,
          posts: posts,
        });
      }
    })
      .sort({ created_at: -1 })
      .populate("category")
      .limit(perPage)
      .skip((currPage - 1) * perPage);
};

Le téléavertisseur dans la vue:

<% if (posts) {%>
  <div class="clearfix d-flex justify-content-center">
    <div class="px-1">
        <a class="btn btn-primary <%= pageDecrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage - pageDecrement %>">&larr; Newer Posts</a>
    </div>

    <div class="px-1">
        <a class="btn btn-primary <%= pageIncrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage + pageIncrement %>">Older Posts &rarr;</a>
    </div>
  </div>
<% } %>

Le problème

La ligne .limit(perPage) du contrôleur donne l'erreur perPage is not defined Dans la console (Git bash).

La solution qui ne fonctionne pas

Clairement, je peux déplacer ces 2 lignes au-dessus de const posts

const perPage = 5;
const currPage = req.query.page ? parseInt(req.query.page) : 1;

mais je peux pas faire la même chose avec const postsCount = posts.length; (dont j'ai également besoin dans la vue).

L'objectif

J'essaie de rendre l'extrait de code concernant la pagination réutilisable (comme un plugin, si possible), car j'ai besoin de paginer pour les messages filtrés par catégorie, ainsi que la liste des articles dans la section admin de l'application.

Qu'est-ce que je fais mal?

3
Razvan Zamfir

Comme expliqué par d'autres commentaires. Cela pourrait simplement être un problème de portée.

exports.getPosts = async (req, res, next) => {
  const perPage = 10; // enable you to use perPage inside getPosts()
  let postsCount = 0; // let, to enable you to use/reassigned postsCount inside getPosts()
  const posts = await Post.find({}, (err, posts) => {
    // ...
    postsCount = posts.length; // updates the variable with the correct count
    // ...
    if (err) {
        console.log("Error: ", err);
      } else {
        res.render("default/index", {
          //...
          posts: posts,
          postsCount: posts.length, // for explicit postsCount in the view

        });
      }

  });

  // ..


pour votre problème avec postsCount dans la vue, puisque vous avez déjà posts dans votre vue

<% if (posts) {%>
  ...
<% } %>

Je pense que vous pouvez simplement utiliser posts.length ou postsCounts dans la vue comme la façon dont vous utilisez les autres (par exemple, pageIncrement, currPage, pageIncrement);

1
Harold Pogi

Peut-être que si vous vérifiez ce composant, vous pouvez résoudre votre problème en voyant comment cela fonctionne

Paginate de mangouste

$ npm install mongoose-paginate

/**
* querying for `all` {} items in `MyModel`
* paginating by second page, 10 items per page (10 results, page 2)
**/

MyModel.paginate({}, 2, 10, function(error, pageCount, paginatedResults) {
 if (error) {
   console.error(error);
 } else {
   console.log('Pages:', pageCount);
   console.log(paginatedResults);
 }
}
1
Daniel Cabrera

Comme je l'ai découvert récemment postsCount = posts.length Compte les messages après ils sont limités par .skip((currPage - 1) * perPage), donc la variable pageIncrement "équation" se transforme en:

let pageIncrement = postsCount >= perPage ? 1 : 0;

Alors je reçois, dans le contrôleur:

exports.getPosts = async (req, res, next) => {

    const perPage = 5;

    const currPage = req.query.page ? parseInt(req.query.page) : 1;

    let postsCount = 0;

    const posts = await Post.find({}, (err, posts) => {

            postsCount = posts.length;

            let pageDecrement = currPage > 1 ? 1 : 0;

            let pageIncrement = postsCount >= perPage ? 1 : 0;

            if (err) {
                console.log('Error: ', err);
            } else {
                res.render('default/index', {
                    moment: moment,
                    layout: 'default/layout',
                    website_name: 'MEAN Blog',
                    page_heading: 'XPress News',
                    page_subheading: 'A MEAN Stack Blogging Application',
                    currPage: currPage,
                    posts: posts,
                    pageDecrement: pageDecrement,
                    pageIncrement: pageIncrement
                });
            }
        })
        .sort({
            created_at: -1
        })
        .populate('category')
        .limit(perPage)
        .skip((currPage - 1) * perPage);
};

Et dans la vue:

<a class="btn btn-primary <%= pageDecrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage - pageDecrement %>">&larr; Newer Posts</a>

et

<a class="btn btn-primary <%= pageIncrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage + pageIncrement %>">Older Posts &rarr;</a>

Cela fonctionne bien à moins qu'il y ait un nombre de messages égal à perPage x N, Où N est un entier, auquel cas le bouton "Articles plus anciens" devient désactivé une page trop tard.

0
Razvan Zamfir