0

I am reading image data from firebase storage and getting the URLs of the images in an array. I console logged the array. It is fine.

I made a variable of img elements through map() function on that array.

That variable is also fine.

But I am not able to render more than one in the component. Only the last image tag renders from the array.

import React, { useRef, useState, useEffect } from 'react'
import { Card, Button, Alert } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import { UseAuth } from '../context/AuthContex'
import app from './../firebase'
import { db } from './../firebase'
import './Dashboard.css'


function Dashboard() {

    const [error, setError] = useState('')
    const { currentUser, logout } = UseAuth()
    const history = useHistory()
    const picURLS = []
    const [photo, setPhoto] = useState()

    async function getPics() {
        const DBRef = db.collection('pics');
        const snapshot = await DBRef.where('author', '==', currentUser.uid).get();
        if (snapshot.empty) {
            console.log('No matching documents.');
            return;
        }

        snapshot.forEach(doc => {
            var storage = app.storage();
            var gsReference = storage.refFromURL('<bucket address>' + doc.data().filename)
            gsReference.getDownloadURL().then(function (url) {
                picURLS.push(url);

            }).catch(function (error) {
                console.log(error)
            });
        });
    }

    useEffect(() => {
        getPics()
        console.log('getPIcs() triggered.')
        console.log(picURLS)
        setPhoto(picURLS.map(postdata => (
            <img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />)))
        console.log(photo)
       

    }, [])



    return (
        <div>
            <div>{photo}</div>
            <div className="menu pmd-floating-action" role="navigation">
                <Link to='/upload-pic' className="pmd-floating-action-btn btn pmd-btn-fab pmd-btn-raised pmd-ripple-effect btn-primary" data-title="Splash New Image?" href="javascript:void(0);">
                    <span className="pmd-floating-hidden">Primary</span>
                    <i className="material-icons pmd-sm">add</i>
                </Link>
            </div>
        </div>


    )
}

export default Dashboard

2 Answers 2

2

It would be better to add picURLS to your state variables because useEffect runs only once with empty dependencies array and setPhoto(picURLS.map) surely would work with an empty picURLS array before it will be filled. So your photo var surely would be empty. You should call your map in the render function;

{picURLS.map(postdata => (
            <img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />))}

Try this code

import React, { useRef, useState, useEffect } from 'react'
import { Card, Button, Alert } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import { UseAuth } from '../context/AuthContex'
import app from './../firebase'
import { db } from './../firebase'
import './Dashboard.css'


function Dashboard() {

    const [error, setError] = useState('')
    const { currentUser, logout } = UseAuth()
    const history = useHistory()
    const [picURLS, setPicURLS] = useState([])

    async function getPics() {
        const DBRef = db.collection('pics');
        const snapshot = await DBRef.where('author', '==', currentUser.uid).get();
        if (snapshot.empty) {
            console.log('No matching documents.');
            return;
        }

        const newUrls = [];
        snapshot.forEach(doc => {
            var storage = app.storage();
            var gsReference = storage.refFromURL('<bucket address>' + doc.data().filename)
            gsReference.getDownloadURL().then(function (url) {
                newUrls.push(url);

            }).catch(function (error) {
                console.log(error)
            });
        });
       setPicURLS(newUrls);
    }

    useEffect(() => {
        getPics()
        console.log('getPIcs() triggered.')
        console.log(picURLS)
    
    }, [])



    return (
        <div>
            <div>{
                   picURLS.map(postdata => (
                     <img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />))}
            </div>
            <div className="menu pmd-floating-action" role="navigation">
                <Link to='/upload-pic' className="pmd-floating-action-btn btn pmd-btn-fab pmd-btn-raised pmd-ripple-effect btn-primary" data-title="Splash New Image?" href="javascript:void(0);">
                    <span className="pmd-floating-hidden">Primary</span>
                    <i className="material-icons pmd-sm">add</i>
                </Link>
            </div>
        </div>


    )
}

export default Dashboard


Sign up to request clarification or add additional context in comments.

1 Comment

It is showing in the state, that is the state is successfully set to URLs. But the render is not showing. That the main issue.
0

photo is array of React components. you need to loop over photo using map array method again to show in render.

{photo.map((img) => { img }}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.