mon goose массив сохранен в неправильном порядке или получена ошибка 'Ошибка преобразования в строку для значения', если схема для массива определена - PullRequest
0 голосов
/ 25 мая 2020

Я работаю над продуктивным приложением с функцией, позволяющей людям выбирать несколько элементов из списка предопределенных элементов (задач) для создания набора личных ежедневных задач и, при необходимости, заполнять одно поле ввода, чтобы изменить продолжительность этой выбранной задачи. в моей схеме 'user' mon goose у меня есть массив 'tasks', и когда пользователь завершит свой выбор задач, список его / ее задач будет сохранен под его данными пользователя, а список по умолчанию не будет изменен. Моя проблема в том, что когда пользователь выбирает некоторые задачи и нажимает «сохранить сегодняшние задачи», массив «задачи» с выбранными объектами сохраняется в базе данных, но вместо этого пары ключ / значение сохраняются для каждого объекта, мое приложение сохраняет массив с ключами в одном объект и значения в другом объекте. вот образец сохраненных данных:

// if defined in userSchema: 
// tasks: [] // just empty array

// what i get now:
"tasks": [
    {
      "title": [
        "Title 01",
        "Title 02",
      ],
      "duration": [
        10,
        20,
      ]
    }
  ]


// what i need:
"tasks": [
    {
      "title": "Title 01",
      "duration": 10
    },{
      "title": "Title 02",
      "duration": 20
    }
  ]

// if defined in userSchema: 
// tasks: [tasksSchema] // array of predefinied objects
// i got just error message
"error": {
    "message": "Cast to string failed for value \"[ 'Title 01', 'Title 02' ]\" at path \"title\"",
    "name": "CastError",
    "stringValue": "\"[ 'Title 01', 'Title 02' ]\"",
    "value": [
      "Title 01",
      "Title 02"
    ],
    "path": "title",
    "reason": null
  }

, а вот остальная часть моего кода (модель, контроллер, представление):

// my model
const tasksSchema = new mongoose.Schema({
  _id: {
    type: mongoose.Schema.ObjectId,
    ref: 'Tasks',
  },
  title: {
    type: String,
  },
  duration: {
    type: Number,
  },
});


const userSchema = new mongoose.Schema(
  {
    title: {
      type: String,
      trim: true,
      required: true,
    },
    tasks: [tasksSchema],
  }
  {
    timestamps: true,
  });

  module.exports = mongoose.model('User', userSchema);

// my controller
exports.updateUser = async (req, res, next) => {
  try {
    const user = await User.findOne({ _id: req.params.id });

    await User.findOneAndUpdate(
      { _id: req.params.id },
      req.body,
      { new: true, runValidators: true },
    ).exec();

    if (!user) {
      return res.status(404).json({
        success: false,
        error: 'no User found',
      });
    }

    return res.redirect('back');
  } catch (err) {
    if (err.name === 'ValidationError') {
      const messages = Object.values(err.errors).map((val) => val.message);
      return res.status(400).json({
        success: false,
        error: messages,
      });
    }
    return res.status(500).json({
      success: false,
      error: err,
    });
  }
};


// my view (pug/jade)
each item in user.tasksList || [] // this list is generated from a model 'Tasks'
  li.sortableItem.ui-state-default.list-group-item(value=item._id id=`id_${item._id}` name="tasks")
    span
      input#title(type='text' name="tasks[title]" value=item.title)
    span 
      input#duration.col-sm-2.input-sm.text-gray(type='number', name="tasks[duration]" value=item.duration)

что я делаю не так? много спасибо!

1 Ответ

0 голосов
/ 26 мая 2020

Если у платформы нет простого способа вернуть эти входные данные в виде массива объектов, вы можете использовать map для создания массива объектов из отдельных массивов перед созданием экземпляра пользователя:

tasks = tasks[0].title.map((e,i) => ({"title":e,"duration":tasks[0].duration[i]}))
...