En utilisant node et express, j'essaie de traiter certaines informations avant que la réponse ne rende la page, mais je n'ai pas de chance de le faire. Aucune suggestion?

app.get("/Category", function (request, response) {
    if (request.query.Id) {
        // get all the posts by categoryId

        ForumPost.find({categoryId: request.query.Id}, function (err, posts) {
            if (err) throw err;

            var usernames = {};

            for (i = 0; i < posts.length; i++) {
                User.findById(posts[i].userId, function (err, user) {
                    if (err) throw err;
                    var username = user.username;
                    usernames[i] = username;
                });
            }
            response.render("Category", {
                message: posts,
                userList: usernames
            });

        });
    }
});
0
JesseS102 4 avril 2017 à 06:15

2 réponses

Meilleure réponse

Vous ne voudrez probablement interroger la base de données qu'une seule fois, en utilisant un seul find avec tous les identifiants utilisateur passés en tant que filtre $in unique, puis assurez-vous de former votre réponse dans le gestionnaire de rappel que mangouste veut que vous pour passer en second argument à la fonction find:

// build the list of all ids you need
var ids = posts.map(p => mongoose.Types.ObjectId(p.userId));

// let's remove duplicates, too
ids = ids.filter((id,pos) => ids.indexOf(id)===pos);

// find all these users in a single query:
User.find({
  '_id': { $in: ids}
}, (err, users) => {
  // handle the query result

  if (err) {
    // do something error related here
    return ...
  }

  // no error: get the usernames and send the response
  var usernames = users.map(user => user.username);
  response.render("Category", {
    message: posts,
    userList: usernames
  });
});

Cela utilise des fonctions fléchées modernes, mais si vous utilisez une ancienne version de Node (pré-6), celles-ci sont facilement remplacées par des signatures de fonction classiques ((a,b,...) => c équivaut à function(a,b,...) { return c }. Techniquement, elles sont { {X2}} mais ce n'est pas une distinction pertinente dans le code ci-dessus).

0
Mike 'Pomax' Kamermans 4 avril 2017 à 04:54

Vous déclenchez en fait beaucoup de découvertes dans la base de données. User.findById est une méthode asynchrone et renvoie une requête, qui peut être convertie en promesse, et éventuellement satisfaite. Donc, ces rappels n'ont pas été nécessairement exécutés au moment où vous appuyez sur

response.render("Category", {
    message: posts,
    userList: usernames
});

Une fois que vous avez rendu une réponse, vos en-têtes de réponse sont envoyés avec ou sans les valeurs appropriées sur la variable de nom d'utilisateur. Jetez un œil à Promises / A +.

0
Fábio Albuquerque 4 avril 2017 à 03:32