Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The image cannot be displayed after posting a new form data

Profile.jsx

const Profile = () => {
    const [auth, setAuth] = useAuth()
    const [name, setName] = useState("")
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [phone, setPhone] = useState("");
    const [address, setAddress] = useState("");
    const [photo, setPhoto] = useState("")
    const navigate = useNavigate()

    console.log(photo.path)

    useEffect(() => {
        const { name, email, phone, address, photo } = auth?.user
        setName(name);
        setPhone(phone);
        setEmail(email);
        setAddress(address);
        setPhoto(photo)
    }, [auth?.user])

    const handleSubmit = async(e) => {
        e.preventDefault()

        const data = new FormData()
        data.append("name", name)
        data.append("email", email)
        data.append("password", password)
        data.append("phone", phone)
        data.append("address", address)
        if(photo){
            data.append("photo", photo)
        }
  
        try{
            const res = await axios.put("http://localhost:4000/api/auth/profile", data)
            if(res.data.success) {
                toast(res.data.message,{type: "success", draggable:false})
                navigate("/")
            } else {
                toast(res.data.message,{type: "error", draggable:false})
            }
        } catch(error){
            console.log(error);
            toast("Something Went Wrong",{type: "error", draggable:false})
        }
    }
    return (
    <form onSubmit={handleSubmit}>
          <div className='input-photo'>
                                        {photo && (
                                            <div>
                                                {/* <img src={photo.path} alt='Profile photo' /> */}
                                                <img src={URL.createObjectURL(photo)} alt='Profile photo' />
                                            </div>
                                        )}
                                        <div className="">
                                            <label>
                                                {photo ? photo.name : "Upload Photo"}
                                                <input type='file' name='photo' accept='image/*'
                                                onChange={(e) => setPhoto(e.target.files[0])} hidden />
                                            </label>
                                        </div>
                                    </div>
    </form>
    )
)

controllers/auth.js

export const updateProfileController = async(req,res) => {
    try{
        const { name, email, password, address, phone } = req.body
        const photo = req.files[0]
        const user = await userModel.findById(req.user._id)

        if(password && password.length < 6){
            return res.json({ error: "Password required and 6 characters long"})
        }

        const hashedPassword = password ? await hashPassword(password) : undefined

        console.log(photo)
        const updatedUser = await userModel.findByIdAndUpdate(req.user._id, 
            {
                name: name || user.name,
                email: email || user.email,
                password: hashedPassword || user.password,
                phone: phone || user.phone,
                address: address || user.address,
                photo: photo || user.photo
            },
            { new: true }
        )
    

        res.status(200).send({
            success: true,
            message: "Profile updated successfully",
            updatedUser,
        });
    } catch(error){
        console.log(error);
        res.status(400).send({
            success: false,
            message: "Error while updating profile",
            error,
        });
    }
}

models/user.js

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 photo: {
            type: {},
        },

I am trying to display the photo that has been saved in MongoDB and since because I used URL.createObjectURL to display so the user can change the profile photo. May I ask how to have the photo first displayed the original ones then when the user clicks on the input field then the photo can be shown as well?

>Solution :

It seems like you’re trying to display a user’s profile photo in your React application, where the photo is initially fetched from MongoDB, and then updated using a file input. You’re currently using URL.createObjectURL to create a temporary URL for previewing the photo, but you need a mechanism to first display the existing photo from the server and then show the updated photo when the user selects a new one.

To achieve this, you should handle the photo URL differently for the initial load (where you display the photo stored in MongoDB) and when the user selects a new photo.

Here’s how you can modify your code:

Display the initial photo from MongoDB: When you fetch the user’s profile, the photo field should contain information about the photo stored in MongoDB. If you store the photo as a path or URL in MongoDB, you can directly use this path/URL to display the image.

Update photo preview on selection: When the user selects a new photo, you can use URL.createObjectURL to create a temporary URL for previewing the new photo.

Here’s an adjustment to your Profile.jsx component:

const Profile = () => {
    // ... other states
    const [photo, setPhoto] = useState("");
    const [photoPreview, setPhotoPreview] = useState("");

    useEffect(() => {
        const { name, email, phone, address, photo } = auth?.user;
        setName(name);
        setEmail(email);
        setPhone(phone);
        setAddress(address);
        setPhoto(photo);

        // Set initial photo preview from MongoDB
        if (photo) {
            // Assuming 'photo' contains a URL or path
            setPhotoPreview(photo); 
        }
    }, [auth?.user]);

    const handlePhotoChange = (e) => {
        const file = e.target.files[0];
        setPhoto(file);
        setPhotoPreview(URL.createObjectURL(file));
    };

    // ... handleSubmit remains the same

    return (
        <form onSubmit={handleSubmit}>
            {/* ... other form fields */}
            <div className='input-photo'>
                {photoPreview && (
                    <div>
                        <img src={photoPreview} alt='Profile photo' />
                    </div>
                )}
                <div>
                    <label>
                        {photo ? photo.name : "Upload Photo"}
                        <input type='file' name='photo' accept='image/*'
                        onChange={handlePhotoChange} hidden />
                    </label>
                </div>
            </div>
        </form>
    );
}

In this modification, photoPreview is used to handle the display of the photo. Initially, it is set to the photo URL/path from MongoDB. When the user selects a new photo, handlePhotoChange updates photoPreview to the new photo’s temporary URL.

Note: Ensure that the server correctly handles the photo update in the updateProfileController and that the path/URL stored in MongoDB points to a location where the photo is accessible to the client.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading