0

I'm trying to write a browser side javascript function that takes an array of 1 or more Firebase Firestore document keys, fetches the documents corresponding to those keys from the Firestore and puts the document data into another array for use elsewhere in my code. The Firestore reads can take a while so I'm using a Promise... then structure to hold up doing anything with the fetched data array until it is complete. My problem is that the .then function is running before the Promise is complete and I can't see why. I'm using code that is a pretty close copy of ideas from w3schools and the Firebase docs, I've changed my code so .then immediately calls my doSomethingWithFetchedData() function instead of invoking it indirectly (SO 51140580) but that didn't work. I'm running out of ideas, all suggestions gratefully received.
I get error messages telling me that stuff from doSomethingWithFetchedData is undefined, then the final console.log statement has data that can only have come from a successful Firestore read.
How do I force the right sequence, so the Promise function runs and completes before the doSomethingWithFetchedData function runs? Why does doSomethingWithFetchedData jump the gun? Here is my code.

function getData(myArray){
    //Given an array of document keys, this function pulls their data out of Firestore
    console.log('Now in getData');
    
    fetchedData = [];  //empty a global array for returned data
        
    myArray.map(function(getData, index){
        
    var docRef = db.collection("cities").doc(myArray[index]);
        docRef.get().then((snapshot) => {
            if (snapshot.exists) {
                fetchedData[index] = snapshot.data() ;
                console.log('fetchedData exists ',fetchedData[index].name);
            } else {
                console.log('No pickup from Firestore');
            };  //closes snapshop.exists
        
        }).catch((error) => { //closes docRef.get opens catch
            console.log("Error getting document:", error);
        });  //closes catch
    });  //closes map function
    return(fetchedData);
};  //closes getData

function doSomethingWithFetchedData(fetchedData){
    console.log('.then bit is working ',fetchedData[0].name);
};

function btnClickResponse(myTinyArray){
    console.log('Starting btnClickResponse');
    /*Code in index.html grabs the id of a just-clicked element, puts it into a 1-item array and calls this function on it.  
    This id is also the id of a Firestore document  */
    
    let aPromise = new Promise(function(aResolve, aReject){
        getData(myTinyArray);
        if (fetchedData.isArray()){  /*Not a good test since fetchedData is a global array but it'll do for now   */
            aResolve(console.log('fetchedData exists'));
        } else {
            aReject(console.log('fetchedData doesnt exist'));
        }
    });
    aPromise.then(
        doSomethingWithFetchedData(fetchedData),
        function(error){console.log('.then bit of btnClickResponse has failed')}
    );  
    console.log('fetchedData has fetched some data ',fetchedData[0].name);
    // expected output: "San Francisco" or similar
    
};```

0 Answers0