Getting URL of locally uploaded image not working?

Viewed 29

Im using the React Grid Gallery to display images on one of my pages. I have it working when the images are already upload, and I'm pulling them in from my database.

The issue I'm having is when I want to display them when uploading them as a preview. After selecting which images to upload from my computer, they wont display in the grid. I'm not totally sure how to do this since they don't have a url(?). I'm new to react still, so any help or guidance in the right direction would be greatly appreciated!

Code:

import React, { useContext, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import BTextfield from '../components/b-textfield';
import { AlertBoxContext } from '../contexts/alertbox-context';
import { AuthContext } from '../contexts/auth-context';
import { DatabaseContext } from '../contexts/database-context';
import { StorageContext } from '../contexts/storage-context';
import Gallery from 'react-grid-gallery';


import '../scss/pages/PropertyAddPage.scss'

function PropertyAddPage() {

    const navigate = useNavigate();
    const navigateTo = (path) => {
        navigate(path)
    }

    const { showAlertBox } = useContext(AlertBoxContext);
    const { selectedLocation, listingAddLoader } = useContext(DatabaseContext);
    const { AddListingImagesAndInfo } = useContext(StorageContext);
    const { user } = useContext(AuthContext);

    let location = localStorage.getItem('location');
    location = JSON.parse(location);

    const mapLocation = selectedLocation || location;

    const [images, setImages] = useState([]);

    const [price, setPrice] = useState('');
    const [bedroomCount, setBedroomCount] = useState('');
    const [bathroomCount, setBathroomCount] = useState('');
    const [sqft, setSqft] = useState('');
    const [description, setDescription] = useState('');

    const hiddenFileInput = useRef(null);

    const handleClick = event => {
        hiddenFileInput.current.click();
    };

    const selectImage = e => {
        if (e.target.files.length <= 8) {
            console.log(e.target.files)
            const files = Object.values(e.target.files)
            files.forEach(i => {
                console.log(i)
                setImages(images => [...images, {
                    preview: URL.createObjectURL(i),
                    raw: i
                }]);

            });
        } else {
            showAlertBox(true, 'danger', "You can't select more than 8 images");
        }
    };

    const getCurrencyConverted = (price) => {
        const converted = (price).toLocaleString('en-US', {
            style: 'currency',
            currency: 'USD',
            maximumFractionDigits: 0
        });

        return converted;
    }

    const postListing = () => {

        const { userId } = user;
        const { lat, lng, address } = mapLocation;
        const listing = {
            address: address?.label,
            bathrooms: bathroomCount + ' Bath',
            bedrooms: bedroomCount + ' Bed',
            creationDate: new Date(),
            description: description,
            latitude: lat,
            longitude: lng,
            postUrl: '',
            poster: userId,
            price: getCurrencyConverted(parseFloat(price)),
            rawPrice: price,
            squareFeet: sqft + ' sqft',
            view_count: 0
        }
        AddListingImagesAndInfo(images, listing);

        resetForm();
        navigate('/home');

    }

    const resetForm = () => {
        setImages([]);
        setPrice('');
        setBedroomCount('');
        setBathroomCount('');
        setSqft('');
        setDescription('');
    }
    return (
        <div className='property-add-page'>

            <div className='titleContainer'>
                <h1 className='titleText'>
                    Let's get the details nailed down now
                </h1>
            </div>

            <div className='property-add-page_container'>

                <div className='property-add-page_container_1'>
                    <Gallery
                        images={Object.values(images).map((url) => ({
                            src: url,
                            thumbnail: url,
                            alt: ' detail images'
                        }))}
                        enableImageSelection={false}
                    />
                </div>
                <div className='property-add-page_container_2'>
                    <div className="column">
                        <BTextfield type={'number'} value={price} onChange={(ev) => setPrice(ev.target.value)} placeholder="Asking Price" />
                    </div>
                    <div className="column">
                        <BTextfield type={'number'} value={bedroomCount} onChange={(ev) => setBedroomCount(ev.target.value)} placeholder="Bedroom Count" />
                    </div>
                    <div className="column">
                        <BTextfield type={'number'} value={bathroomCount} onChange={(ev) => setBathroomCount(ev.target.value)} placeholder="Bathroom Count" />
                    </div>
                    <div className="column">
                        <BTextfield type={'number'} value={sqft} onChange={(ev) => setSqft(ev.target.value)} placeholder="Sqft." />
                    </div>
                    <textarea className="textarea" placeholder="Add a description of the property!" value={description} onChange={(ev) => setDescription(ev.target.value)}></textarea>
                    <div className='sellButtonContainer'>
                        <button
                            className={
                                "sellButton " +
                                (listingAddLoader ? "is-loading " : " ")
                            }
                            onClick={() => handleClick()}
                            disabled={listingAddLoader}
                        >
                            Add Images
                        </button>

                        {images.length > 0 && <p>{images.length} Images are ready to go!</p>}

                        <button
                            className={
                                "sellButton " +
                                (listingAddLoader ? "is-loading " : " ")
                            }
                            onClick={() => postListing()}
                            disabled={listingAddLoader}
                        >
                            Post
                        </button>
                    </div>
                </div>

                <input
                    type="file"
                    ref={hiddenFileInput}
                    onChange={selectImage}
                    accept="image/*"
                    multiple={true}
                    style={{ display: 'none' }} />

            </div>

        </div>
    )
}

export default PropertyAddPage;
1 Answers

Okay putting this here for reference in case there is a one-off chance someone has the same question. I figured it out and got it to work. Here is the code I used to map the images and get the url for a preview:

    <Gallery
    images={images.map((images) => ({
    src: images.preview,
    thumbnail: images.preview,
    alt: 'property detail images'
}))}
    enableImageSelection={false}
    />
Related