0

I am trying to create MERN stack app with the function creating job posts with json data (company name, position etc) and the image (company logo).

I use multer and cloudinary to upload and save image, and mongo db to save file path. I cannot send POST request on POSTMAN with json data and image file at the same time, so I cannot test if my code actually works. Could someone verify it or help me how to send json and file at the same time?

Job.js in models

const mongoose = require('mongoose');
const slugify = require('slugify');

const JobSchema = new mongoose.Schema({
  company: {
    type: String,
    required: [true, 'Please add a company'],
    trim: true,
    maxlength: [50, 'Company name can not be more than 50 characters'],
  },
  slug: String,
  logo: {
    type: String,
    required: [true, 'Please add a logo'],
  },
  new: {
    type: Boolean,
    default: false,
  },
  featured: {
    type: Boolean,
    default: false,
  },
  position: {
    type: String,
    required: [true, 'Please add a position'],
    maxlength: [100, '`Position` can not be more than 50 characters'],
  },
  role: {
    type: String,
    required: true,
    enum: ['Frontend', 'Fullstack', 'Backend'],
  },
  level: {
    type: String,
    required: true,
    enum: ['Junior', 'Midweight', 'Senior'],
  },
  postedAt: {
    type: String,
    required: true,
    // need to be "-d ago"
    // type: Date,
    // default: Date.now,
  },
  contract: {
    type: String,
    required: true,
    enum: ['Full Time', 'Part Time', 'Contract'],
  },
  location: { type: String, required: [true, 'Please add a location'] },
  languages: { type: [String], required: [true, 'Please add languages'] },
  tools: { type: [String], required: false },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

// Create job slug from the company name
JobSchema.pre('save', function (next) {
  this.slug = slugify(this.company, { lower: true });
  next();
});

module.exports = mongoose.model('Job', JobSchema);

jobs.js in controllers

const ErrorResponse = require('../utils/errorResponse');
const asyncHandler = require('../middleware/async');
const Job = require('../models/Job');

// @desc Create single job
// @routes POST /api/jobs
// @access Private
exports.createJob = asyncHandler(async (req, res, next) => {
  const job = await Job.create({ ...req.body, logo: req.file.path });

  res.status(201).json({
    success: true,
    data: job,
  });
});

jobs.js in routes*

const express = require('express');
const parser = require('../middleware/cloudinary');
const {
  getJobs,
  getJob,
  createJob,
  updateJob,
  deleteJob,
} = require('../controllers/jobs');

const router = express.Router();

router.route('/').get(getJobs).post(parser.single('logo'), createJob);

router.route('/:id').get(getJob).put(updateJob).delete(deleteJob);

module.exports = router;

server.js

const path = require('path');
const express = require('express');
const dotenv = require('dotenv');
const morgan = require('morgan');
const errorHandler = require('./middleware/error');
const connectDB = require('./config/db');

// Load env vars
dotenv.config({ path: './config/config.env' });

// Connect to database
connectDB();

// Route file
const jobRoutes = require('./routes/jobs');

// express app
const app = express();

// Body parser
app.use(express.json());

// Dev logging middleware
if (process.env.NODE_ENV === 'development') {
  app.use(morgan('dev'));
}

// routes
app.use('/api/jobs', jobRoutes);

app.use(errorHandler);

// listen for requests
const PORT = process.env.PORT || 5000;
const server = app.listen(
  PORT,
  console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`)
);

// Handle unhandled promise rejections
process.on('unhandledRejection', (err, promise) => {
  console.log(`Error: ${err.message}`);
  // Close server & exit process
  server.close(() => process.exit(1));
});

cloudinary.js in middleware

const multer = require('multer');
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');

const { CLOUDINARY_HOST, CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET } =
  process.env;

cloudinary.config({
  cloud_name: CLOUDINARY_HOST,
  api_key: CLOUDINARY_API_KEY,
  api_secret: CLOUDINARY_API_SECRET,
});

const storage = new CloudinaryStorage({
  cloudinary: cloudinary,
  params: {
    folder: 'folder name',
    format: async (req, file) => 'svg',
    public_id: (req, file) => file.filename,
  },
});

const parser = multer({ storage: storage });

module.exports = parser;
Yuko
  • 31
  • 8
  • what error do you get when you make a request with postman? – Sammy Dec 29 '22 at 06:34
  • @Sammy Sorry for late in reply, the error on postman is `{ "success": false, "error": "Please add a location,Path `contract` is required.,Path `postedAt` is required.,Path `level` is required.,Path `role` is required.,Please add a position,Please add a company" }` – Yuko Dec 30 '22 at 04:10
  • @Sammy because I set other fields are required in model – Yuko Dec 30 '22 at 04:11

0 Answers0