i'm trying to code a feature on my website that lets the user upload their own profile picture. It's also my first time using the MERN stack so here's the code i wrote:
Frontend:
Settings.tsx
import React, { useEffect, useState } from "react";
import axios from "axios";
import Image from "next/image";
import iconDefault from "../assets/random/user.png";
const Settings = () => {
const [isEditing, setIsEditing] = useState<boolean>(false);
const [file, setFile] = useState<any | null>(null);
const [picture, setPicture] = useState<any | null>(null);
const cookies = new Cookies();
const user = getUserCookie();
const [updatedUser, setUpdatedUser] = useState<User>(user);
const handleEdit = () => {
setIsEditing(!isEditing);
};
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
const { name, value } = e.target;
setUpdatedUser((prevUser) => ({
...prevUser,
[name]: value,
}));
};
const upload_preset = ".....";
const cloud_name = ".....";
const submitImage = async () => {
const data = new FormData();
data.append("file", file);
data.append("upload_preset", upload_preset);
data.append("cloud_name", cloud_name);
try {
const res = await axios.post(
`https://api.cloudinary.com/v1_1/${cloud_name}/image/upload`,
data
);
const cloudinaryUrl = res.data.secure_url;
setPicture(cloudinaryUrl);
const updatedUserWithImage = { ...updatedUser, icon: cloudinaryUrl };
await editUser(updatedUserWithImage);
} catch (err) {
console.log("error uploading icon", err);
}
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
if (file) {
await submitImage();
} else {
await editUser(updatedUser);
}
window.location.reload();
} catch (err) {
console.log("error updating icon: ", err);
}
};
const editUser = async (updatedUser: User) => {
const token = cookies.get("token");
try {
await axios.patch(
process.env.MONGODB_URL + `/users/${user?._id}`,
updatedUser,
{
// .patch(`http://localhost:3005` + `/users/${user?._id}`, updatedUser, {
headers: {
Authorization: `Bearer ${token}`,
},
}
);
const response = await axios.get(
process.env.MONGODB_URL + `/users/${user?._id}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
const updatedUserFromServer = response.data;
document.cookie = `user=${JSON.stringify(updatedUserFromServer)}; path=/`;
console.log("Updated User:", updatedUserFromServer);
} catch (err) {
console.log("error updating user: ", err);
}
};
return (
<div className="settings">
<main>
<header className="header__welcome card ">
<div>
{user ? <h1>Hello, {user.name}!</h1> : <h1>Loading user...</h1>}
<h2>Edit here your profile info</h2>
</div>
</header>
<div className="form-container">
<form onSubmit={handleSubmit} className="form-settings">
<div className="form-settings__left">
<div>
{user.icon ? (
<Image
className="icon-settings"
src={user.icon}
width="400"
height="400"
alt="icon"
/>
) : (
<Image
className="icon-settings"
src={iconDefault}
width="400"
height="400"
alt="iconDefault"
/>
)}
</div>
<div className="rainbow__button">
<label htmlFor="icon">Edit profile picture</label>
<input
type="file"
name="icon"
className="input-settings"
onChange={(e) => setFile(e.target.files?.[0] || null)}
/>
</div>
</div>
{......}
<div className="buttons">
<button
className="buttons__addtask rainbow__button"
type="submit"
>
Save changes
</button>
<hr></hr>
<DeleteUser />
</div>
</div>
</form>
</div>
</main>
</div>
);
};
export default Settings;
But when i choose the image and submit the form i get this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.cloudinary.com/v1_1/---/image/upload. (Reason: header ‘authorization’ is not allowed according to header ‘Access-Control-Allow-Headers’ from CORS preflight response).
XHRPOST https://api.cloudinary.com/v1_1/---/image/upload
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.cloudinary.com/v1_1/----/image/upload. (Reason: CORS request did not succeed). Status code: (null).
error uploading icon
i put my preset key on Cloudinary to "unsigned" already but it still doesn't work, i don't know what else to do. Can anyone help?
edit: i'd like to mention that this happened before but i managed to fix it: i realised that the mongodb document/user i was trying to update from the frontend didn't have a "icon" value, so i created it and it worked just fine, i even changed profile pictures a few times on the same user and it worked. Now it's happening again and i'm not sure what's the reason this time.