如何将图像上传到 Cloudinary - MERN 堆栈

How to upload Image to Cloudinary - MERN Stack

我想向 mongo 数据库添加一些公司详细信息,这些详细信息包括公司徽标。所以我想将图片上传到 Cloudinary,然后将 URL 与其他详细信息一起保存在 Mongo 数据库中。

但我的代码似乎不起作用。当我填写表格并单击提交时,图像会上传到 Cloudinary,但不会保存在数据库中。

存储图片

const [ companyLogo, setCompanyLogo] = useState("");
const [ companyLogoURL, setCompanyLogoURL] = useState("");

提交时执行的函数

const handleCompanySubmit = (evt) => {
    evt.preventDefault();

    const data = new FormData()
    data.append("file", companyLogo)
    data.append("upload_preset", "Sprint")
    data.append("cloud_name", "sprint-ccp")
    fetch("https://api.cloudinary.com/v1_1/sprint-ccp/image/upload",{
      method:"post",
      body:data
    })
    .then(res => res.json())
    .then(data => {
      setCompanyLogoURL(data.url)
    })
    .catch(err => {
      console.log(err)
    })

    //check for empty fields
    if (
      isEmpty(companyName) ||
      isEmpty(companyAddress) ||
      isEmpty(companyRegNumber) ||
      isEmpty(companyContactNumber)
    ) {
      setCompanyErrorMsg("Please Fill All The Fields");
    }else {
      let formData = new FormData();
      formData.append('companyName', companyName);
      formData.append('companyAddress', companyAddress);
      formData.append('companyRegNumber', companyRegNumber);
      formData.append('companyContactNumber', companyContactNumber);
      formData.append('companyLogo', companyLogoURL);

      setCompanyLoading(true);

      addCompany(formData)
      .then((response) => {
        setCompanyLoading(false);
          setCompanySuccessMsg(response.data.successMsg)
          setCompanyData({
            companyName: "",
            companyAddress: "",
            companyRegNumber: "",
            companyContactNumber: ""
          });
      })
      .catch((err) => {
        setCompanyLoading(false);
        setCompanyErrorMsg(err.response.data.errorMsg)
      })
    }
  };

const handleCompanyLogo = (evt) => {
    setCompanyLogo(evt.target.files[0])
  };

前端视图

<form className="register-form" onSubmit={handleCompanySubmit} noValidate>

     <label className="text-secondary">Company Logo :</label>
     <input type="file"  className="form-control" onChange={handleCompanyLogo}/>

     //remaining input fields

     <button className="btn btn-info submitButton" >Submit</button>
                  
</form>
    
    

api 用于添加公司

export const addCompany = async (data) => {
    const config = {
      headers: {
        "Content-Type": "application/json",
      },
    };
  
    const response = await axios.post(
      "http://localhost:5000/api/auth/clients/company",
      data,
      config
    );
  
    return response;
  };

后端控制器

exports.addNewCompany = async(req,res)=>{

  const { 
    companyName,
    companyAddress,
    companyRegNumber,
    companyContactNumber,
    companyLogo
  } = req.body;

  const company = await Company.findOne({ companyName });
    if (company) {
      return res.status(400).json({
        errorMsg: `${req.body.companyName} already exists`,
      });
    }

  try{
    const newCompany = new Company();
    newCompany.companyName = companyName;
    newCompany.companyAddress = companyAddress;
    newCompany.companyRegNumber = companyRegNumber;
    newCompany.companyContactNumber = companyContactNumber;
    newCompany.companyLogo = companyLogo;

    await newCompany.save();
    res.json({
      successMsg: `${req.body.companyName} Company Added Successfully`
    });
  } catch (err) {
    console.log("clientsController error - Add Company ", err);
    res.status(500).json({
      errorMsg: "Server Error. Please Try again",
    });
  }
};

我在控制台中得到的错误是这样的

clientsController 错误 - 添加公司错误:公司验证失败:公司徽标:需要路径 companyLogo 在 ValidationError.inspect

(C:\CCP\sd08_2021\Backend\node_modules\mongoose\lib\error\validation.js:47:26)

你能帮帮我吗?

我认为你的错误是由一个更微不足道的问题引起的:

当你用fetch发送POST请求时,实际上并没有等待它完成(这是一个promise),所以if ... else {...}语句中的代码被执行了在 fetch() 终止之前 !

setCompanyLogoURL(data.url) 还没有被调用,所以 formData.append('companyLogo', companyLogoURL); 设置一个空白字符串而不是调用 Cloudinary API.

返回的值

解决方案是使handleCompanySubmit异步,并等待fetch()承诺完成。