Recientemente comencé a trabajar en un proyecto en el que el administrador puede crear recorridos en línea al completar un formulario. Al completar el formulario, la información que se introducirá intro un Mongoose Schema y cree JSON.

En el archivo createcontent.js toma los datos del formulario, utilicé new FormData(); porque para cargar imágenes utilizo una llamada de módulo multer .

const createTour_form = document.querySelector('.form-create__tour');
if (createTour_form) {
    createTour_form.addEventListener('submit', (cr) => {
        cr.preventDefault();

        const create = new FormData();
        // Name
        create.append('name', document.getElementById('tour_name').value);
        //Tour Duration
        create.append('duration', document.getElementById('tour_duration').value);
        //Number Participoants
        create.append('maxGroupSize', document.getElementById('tour_participants').value);
        //Tour Difficulty
        create.append('difficulty', document.getElementById('tour_difficulty').value);
        //Tour Price
        create.append('price', document.getElementById('tour_prices').value);
        //Short Description
        create.append('summary', document.getElementById('tour_short_des').value);
        //Description
        create.append('description', document.getElementById('tour_long_des').value);

        createTour(create);
    })
}

Utilizo un módulo slugify para convertir el nombre del recorrido en un slug que utilizo en la URL. Este es mi esquema de mangosta:

const tourchema = new mongoose.Schema({
    name: {
        type: String,
        require: [true, 'A tour mush have a name'],
        unique: true,
        trim: true,
        maxlength: [50, 'A tour name must have less or equal then 50 characters'],
        minlength: [10, 'A tour name must have more or equal then 10 characters'],
        //validate:[validator.isAlpha, 'Tour name must only contain characters']
    },
    slug: {
        formType: String
    },
    duration: {
        type: Number,
        require: [true, 'A tour must have a duration']
    },
    maxGroupSize: {
        type: Number,
        require: [true, 'A tour must have a group size']
    },
    difficulty: {
        type: String,
        require: [true, 'A tour must have a difficulty'],
        enum: {
            values: ['easy', 'medium', 'difficult'],
            message: 'Difficulty is either: easy, medium, difficult'
        }
    },
    ratingsAverage: {
        type: Number,
        default: 4.5,
        min: [1, 'Raiting must be above 1.0'],
        max: [5, 'Raiting must be below 5.0'],
        set: val => Math.round(val * 10) / 10
    },
    ratingsQuantity: {
        type: Number,
        default: 0
    },
    price: {
        type: Number,
        require: [true, 'A tour must have a price']
    },
    priceDiscount: {
        type: Number,
        validate: {
            validator: function (val) {
                //his only points to create doc on new document creation
                return val < this.price;
            },
            message: 'Discount price ({VALUE}) shoud be below the regular price'
        }
    },
    summary: {
        type: String,
        trim: true,
        require: [true, 'A tour must have a description']
    },
    description: {
        type: String,
        trim: true
    },
    imageCover: {
        type: String,
        require: [true, 'A tour must have a cover image']
    },
    images: [String],
    createdAt: {
        type: Date,
        default: Date.now()

    },
    startDates: [Date],
    secretTour: {
        type: Boolean,
        default: false
    },
    startLocation: {
        //GeoJSON
        type: {
            formType: String,
            default: 'Point',
            enum: ['Point']
        },
        coordinates: [Number],
        adress: String,
        description: String
    },
    locations: [
        {
            type: {
                type: String,
                default: 'Point',
                enum: ['Point']

            },
            coordinates: [Number],
            adress: String,
            description: String,
            day: Number
        }
    ],
    // guides:Array
    guides: [
        {
            type: mongoose.Schema.ObjectId,
            ref: 'User'
        }
    ]
}

tourchema.index({ slug: 1 });
tourchema.pre('save', function (next) {
    this.slug = slugify(this.name, { lower: true });
    next();
});

Cuando subo datos desde un formulario usando axios con función asincrónica:

import axios from 'axios';
import { showAlert } from './alert';

export const createTour = async(data)=>{
  try{
     const create_tour = await axios({
          method:'POST',
          url:'http://127.0.0.1:3000/api/v1/tours',
          data:data
     });
  }
  catch(err){
       console.log(err);
       showAlert('error',err.response.data.message); 
  }
}

Cuando tiene lugar la acción de referencia, se produce un error slugify: se espera un argumento de cadena No encontré nada en Internet sobre este error. Intenté construir mi propia función para reemplazar el módulo pero no funcionó, ¿no hay solución para resolver este error?

0
Pruteanu Alexandru 20 jul. 2020 a las 23:47

1 respuesta

La mejor respuesta

Puede convertir "FormData" en un objeto y luego analizarlo

function formDataToObj(formData) {
    let obj = {};
    for (let key of formData.keys()) {
        obj[key] = formData.get(key)
    }
    return obj;
}

Ejemplo:

function formDataToObj(formData) {
  let obj = {};
  for (let key of formData.keys()) {
    obj[key] = formData.get(key)
  }
  return obj;
}
    

const fd = new FormData()
fd.append('a', 1)
fd.append('b', 2)
const obj = formDataToObj(fd)
console.log( obj )
const json = JSON.stringify( obj )
console.log( json )
0
Yoel Duran 20 jul. 2020 a las 23:07