2 votes

Rendu des résultats de la base de données mongodb à partir d'une requête POST dans un wrapper .ajax jquery en node js

Je suis en train de créer une fonctionnalité de base pour permettre aux utilisateurs d'envoyer leur position à un serveur qui interroge ensuite une base de données et renvoie les emplacements proches d'eux. J'utilise le wrapper jQuery .ajax ci-dessous pour envoyer des données au serveur. Celles-ci prennent la forme d'un point de latlon qui est ensuite utilisé comme base pour une recherche géographique dans MongoDB en utilisant nodejs et express sur le backend. Les résultats de la recherche sont ensuite destinés à être renvoyés au client et rendus par la fonction createMapListings.

La page /find est initialement rendue par une requête GET à la base de données via mongodb séparée du code ci-dessous. Cependant, après le rendu initial, je veux ensuite renvoyer les résultats en fonction de l'emplacement fourni.

La méthode POST fonctionne bien et l'emplacement est affiché sur le serveur. Les résultats de la recherche sont renvoyés et je peux en imprimer le contenu dans le journal de la console.

Cependant, je veux ensuite rendre les résultats du côté client. Comme indiqué, les résultats de la recherche s'affichent dans la console, mais lorsque j'essaie de passer au client, je peux afficher les données elles-mêmes (sous la forme d'un tableau d'objets) dans le div #output, mais la fonction createMapListings ne semble pas attraper les données.

En fait, la fonction ci-dessous semble être appelée, mais elle imprime plus de mille lignes avec les données qui devraient être capturées et décrites comme "indéfinies". J'ai essayé d'utiliser res.render et res.redirect, mais dans le premier cas, la vue est rendue dans le div (ce qui est attendu, je suppose) et la redirection échoue.

La fonction createMapListings fonctionne bien lorsqu'une simple requête GET est adressée au serveur, par exemple pour tous les objets d'une collection, à l'aide du modèle ejs. Cependant, je pense que le problème ici peut être une combinaison d'une requête POST et de la volonté de renvoyer les résultats à la requête AJAX en utilisant le callback complet.

Je m'excuse si le code ci-dessous est quelque peu obtus. Je suis définitivement ce qu'on pourrait appeler un débutant. Je comprends que la fonctionnalité ci-dessus peut ne pas être possible, donc s'il y a une meilleure façon, je serais bien sûr ouvert à elle (res.direct peut-être).

Voici le script côté client pertinent :

$(document).ready(function(){

$("#geolocate").click(function(){ 
navigator.geolocation.getCurrentPosition(geolocate, function(){

        });
     });
 });

function geolocate(pos){
     var latlonpt = [];
     var x = pos.coords.latitude;
     var y = pos.coords.longitude;
     latlonpt.push(x);
     latlonpt.push(y); 

    var obj = {
    userlocation: latitudelongitudept
    };

   $.ajax({
    url: "/find",
    type: "POST",
    contentType: "application/json",
    processData: false,
    data: JSON.stringify(obj),
    complete: function (data) {
        $('#output').html(data.responseText);
        $('#infooutput').children().remove();
        createMapListings(data.responseText); 
        }
     });
 };

 function createMapListings(maps) {
 for (var i = 0; i < maps.length; i++) {
 var url = maps[i]._id;
 var fullurl = "<a href="stackoverflow.com/show?id=" + url + "'>Route</a></div>";
 var title = "<div>" + maps[i].title + " - " + fullurl +"";
 $('#infooutput').append(title);

     };
  };

 </script>

Voici la route pertinente utilisée dans une application express de base pour traiter la requête post faite par le wrapper .ajax ci-dessus.

 exports.findbylocation = function(req, res) {
 console.log(req.body.userlocation);
 var userlocation = req.body.userlocation;
 Map.ensureIndexes;
 Map.find({loc :{ $near : userlocation }}, function(err, maps) {

 if (err) { 
          console.log(err)
          }
 else {    
       var jmaps = JSON.stringify(maps);
       console.log(jmaps);
       res.send(jmaps);
      }      
   });
};

4voto

cantlin Points 1466

Par convention, le data le nom de la variable dans un $.ajax La signature du rappel fait référence au corps de la réponse HTTP analysé. Puisque votre callback est sur complete nous sommes en fait passés devant le XMLHttpRequest utilisé, par convention appelé xhr . Vous saisissez à juste titre le responseText mais elle doit être analysée pour être utile. Tant que nous faisons attention à notre Content-Type et ne désactivez pas explicitement l'option processData Si l'on utilise des objets, jQuery s'occupe de l'encodage et du désencodage pour nous. C'est une bonne chose, car le format de transport n'a généralement pas d'importance particulière pour la logique de l'application. Si nous utilisons res.json(maps) à la place de res.send(jmaps) nous pouvons écrire notre appel plus simplement :

$.ajax({
    url:  '/find',
    type: 'POST',
    data: obj,

    success: function(data) {},
    error:   function(xhr, text, err) {}
});

Ici data est un objet Javascript déjà analysé et prêt à être utilisé. Nous utilisons également un application/x-www-form-urlencoded plutôt que de définir explicitement un contentType . C'est la même chose en ce qui concerne express : il sera simplement analysé par urlencodé au lieu de json .

0voto

saeed Points 969

En supposant que vous ayez résolu votre problème de client-sie.

Comme vous utilisez express, il n'y a pas besoin de JSON.stringfy , vous pouvez utiliser res.json(maps) .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X