Warm tip: This article is reproduced from serverfault.com, please click

Trying to update MongoDB with jQuery, jQuery UI Sortable, and Express JS

发布于 2020-11-28 10:14:24

I have a list of names that I want to re-submit to the Express app after each re-sorting with jQuery UI Sortable Widget and then save to my Mongo database. I can successfully re-sort list items, the data order is correct in my browser's console, but I can't figure how to send/receive it correctly on the node's side. If I stringify the data array whole array is saved as the key of the first object, but if I do not stringify a data then nothing is sent (data object is empty). Here is my code shorten for brevity:

In my frontend/jQuery javascript file

$(".favList")
    .sortable({
      connectWith: ".favDetail",
      update: function (event, ui) {
        var lis = $(".favList .favDetail");
        var ids = lis
          .map(function (i, el) {
            return {
              first: el.dataset.first,
              last: el.dataset.last,
            };
          })
          .get();

        var data = JSON.stringify(ids);
        // var data = ids;

        $.ajax({
          type: "POST",
          url: "/people/" + id + "/sortPeople",
          data: data,
        })
          .done(function (response) {
            console.log("OK", data);
          })
          .fail(function (response) {
            console.log("Error", response);
          });
      },
    })
    .disableSelection();

Browser's console log output (ALL IS OK):

data: [{id: "5fbf6cdabec1197e4514e7cb", first: "Boba", last: "Fett"},
{id: "5fbf6cdabec1197e4514e7ca", first: "Jango", last: "Fett"},
{id: "5fbf6cdabec1197e4514e7cc", first: "Aurra", last: "Sing"}]

My Express JS controller and router:

const people = await People.findOne({
  _id: req.params.id,
});

await People.findOneAndUpdate(
  { _id: req.params.id },
  { favPeople: req.body },
).exec();

router.route('/:id/sortPeople').post(sortPeople);

My 'People' Mongoose model

const mongoose = require('mongoose');
const peopleSchema = new mongoose.Schema(
  {
    title: {
      type: String,
      trim: true,
      required: true,
    },
    favPeople: [
      {
        id: mongoose.Schema.ObjectId,
        first: String,
        last: String,
      },
    ],
    // favPeople: [],
  },
  {
    timestamps: true,
  },
);

module.exports = mongoose.model('People', peopleSchema);

Node's console log output: (NOT OK -- array is saved as a key of the first and only object, not as an array of objects):

data: {
 '{"id": "5fbf6cdabec1197e4514e7cb", first: "Boba", last: "Fett"},{"id": "5fbf6cdabec1197e4514e7ca", first: "Jango", last: "Fett"},{"id": "5fbf6cdabec1197e4514e7cc", first: "Aurra", last: "Sing"}': ''
}

If I don't use JSON.stringify() method, nothing is received in the Express app: (Node's console log output):

data:  { undefined: [ '', '', '' ] }

What I want to receive in the Express app is the same updated array I have in my browser console (ie):

data: [{id: "5fbf6cdabec1197e4514e7cb", first: "Boba", last: "Fett"},
{id: "5fbf6cdabec1197e4514e7ca", first: "Jango", last: "Fett"},
{id: "5fbf6cdabec1197e4514e7cc", first: "Aurra", last: "Sing"}]

Any help is much appreciated! Thank you!

Questioner
user549385
Viewed
1
user549385 2020-11-29 06:59:10

I have found a solution. To pass data correctly to the controller, 'dataType' and 'contentType' has to be included. Here is my updated working code:

$.ajax({
  type: "POST",
  dataType: "json",
  contentType: "application/json",
  url: "/people/" + id + "/sortPeople",
  data: JSON.stringify(ids),
})