0

Have MERN appication Everything was working fine when I was testing in POSTMAN.

If you select a video file with POSTMAN. you will get correct error in response "That only Image should uploaded" which is what expected

But tried same thing using react then after sending the req, not getting anything back, code stops running at fetch request in react

If you restart the node server Only then you're getting response back in reactApp.

NOTE- Only getting this problem while uploading Videos. Other format files giving me back response fine.

Note - Data of logged in user is already stored in req.user

NODE server =  http://localhost:4000
React Url = http://localhost:5173

server.js

app.use('/user' UserRoute)


**UserController.Js**

const AppError = require("../utils/appError");
const User = require("../model/userModel");
const catchAsync = require("../utils/catchError");
const handlerFactory = require("./handlerFactory");
const multer = require("multer");
const cloudinary = require("cloudinary").v2;


cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
});



exports.getMe = async (req, res, next) => {
  req.params.id = req.user.id;
  next();
};


exports.passwordAndEmailCheck = catchAsync(async (req, res, next) => {
  if (
    req.body.password ||
    req.body.confirmPassword ||
    req.body.passwordChangeAt ||
    req.body.email
  ) {
    return next(
      new AppError(
        "To update password or email use /users/update-password/ or /users/update-email/ route",
        404
      )
    );
  }



const multerFilter = (req, file, cb) => {
  if (file.mimetype.startsWith("image")) {
    console.log("Valid File")
    return cb(null, true);
  } else {
  console.log("Not a valid File")

    return cb(
      new AppError("Not an image! Please upload only images.", 400),
      false
    );
  }
};

const upload = multer({
  storage: multer.diskStorage({}),
  fileFilter: multerFilter,
});


exports.uploadUserPhoto = upload.single("image");

exports.hashImageUrl = catchAsync(async (req, res, next) => {
  if (!req.file) {
    return next();
  }
  if (req.file.size > 5 * 1024 * 1024)
    return next(
      new AppError(`Please upload a file with size less than 5MB!`, 400)
  );
  const publicId = req.user.publicId;
  if (publicId) {
    await cloudinary.uploader.destroy(publicId);
  }

  const result = await cloudinary.uploader.upload(req.file.path, {
    folder: "user-images",
    format: "jpg",
    transformation: [
      { width: 400, height: 400, crop: "fill", gravity: "face", quality: 90 },
    ],
  });

  req.user.publicId = result.public_id;
  req.user.imageUrl = result.secure_url;
  next();
});

exports.updateUserDetails =>
  catchAsync(async (req, res, next) => {
    const doc = await User.findByIdAndUpdate(req.params.id, {...req.body, image:req.user.imageUrl, publicId:req.user.publicId}, {
      new: true,
      runValidators: true,
    })

    if (!doc) {
      next(new AppError(`Invalid user ID`, 404));
      return;
    }

    res.status(201).json({
      status: "success",
      data: doc,
    });
  });

```

```
Update User Routes

router.patch(
  "/update-details",
  userController.getMe,
  userController.passwordAndEmailCheck,
  userController.uploadUserPhoto,
  userController.hashImageUrl,
  userController.updateUserDetails
);

```


```
UserModel.js

const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const crypto = require("crypto");
const validator = require("validator");

const User = new mongoose.Schema({
  name: {
    type: String,
    required: [true, "name is required"],
    maxLength: [50, "name should be upto 50 characters"],
    trim: true,
  },
  email: {
    type: String,
    required: [true, "email is required"],
    unique: [true, "email should be unique"],
    lowercase: true,
    validate: [validator.isEmail, "Please provide a valid email"],
  },
  image: {
    type: String,
    default:"default.jpg"
  },
  publicId:{
    type:String
  },
  role: {
    type: String,
    enum: ["admin", "user", "guide", "lead-guide"],
    default: "user",
  },
  password: {
    type: String,
    required: [true, "A password is required"],
    minLenght: [8, "A password must have minimum length of 8 characters"],
    select: false,
  },
  confirmPassword: {
    type: String,
    required: [true, "A password is required"],
    minLenght: [8, "A password must have minimum length of 8 characters"],
    validate: {
      validator: function (el) {
        return el === this.password;
      },
      messsage: "Passwords doesn't match",
    },
  },
  passwordChangeAt: {
    type: Date,
  },
  passwordResetToken: String,
  resetTokenExpiresIn: Date,
  active: {
    type: Boolean,
    select: false,
    default: true,
  },
});

module.exports = mongoose.model("users", User);

```


```
**AppError.js**


class AppError extends Error{
    constructor(message, statusCode){
        super(message)
        this.statusCode = statusCode
        this.status = `${statusCode}`.startsWith("4")?"fail":"error"
        this.isOperational = true
        Error.captureStackTrace(this, this.constructor)
    }
}

module.exports = AppError
```

```
CatchAsync.js

module.exports = fn => {
    return (req, res, next) => {
      fn(req, res, next).catch(next);
    };
  };
```

**REACT CODE**

API URL = http://localhost:4000/users/update-details
 

```
import { useState } from "react";
import Cookies from "js-cookie";
const Form = () => {
  const [name, setName] = useState("");
  const [photo, setPhoto] = useState(null);
  const [sending, setSending] = useState(false)

  const handleSubmit = async (e) => {
    e.preventDefault();
    setSending(true)
    const jwtToken = Cookies.get("jwtToken");

    const formData = new FormData();
      formData.append("image", photo);
      const res = await fetch("http://localhost:4000/users/update-details", {
        method: "PATCH",
        body: formData,
        headers: {
          Authorization: `Bearer ${jwtToken}`,
        },
      });
      console.log(res)
      const data = await res.json();
      setSending(false)
    };

  return (
    <div className="form-cont">
      <h1 className="h1">FORM</h1>
      <form className="form" onSubmit={handleSubmit}>
        <input
          type="text"
          name="name"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
        <input
          type="file"
          name="photo"
          accept="image/*"
          onChange={(e) => {
            setPhoto(e.target.files[0]);
          }}
        />
        <button className="button" type="submit">
          Submit
        </button>
        {sending && <h1>Sending....</h1>}
      </form>
    </div>
  );
};

export default Form;
```


New to node haven't tried much just some console.log's

0 Answers0