Home > database >  Firebase Promise Returning Undefined Data Javascript
Firebase Promise Returning Undefined Data Javascript

Time:03-16

I've followed several guides on how to correctly wait for the data from my ListFile() function. I have logged the output to the console in ListFile() so I know the data is correct. When I try and await for the function to complete and log the data, I get one of two outputs when experimenting with awaits and promises:

getData error: TypeError: undefined is not an object (evaluating 'response.json')

or

Promise {
  "_U": 0,
  "_V": 0,
  "_W": null,
  "_X": null,
}

I'm creating a React Native app and the function that calls ListFile() contains a bunch of other components that are rendered so I can't make the entire function an async function. Not sure what else to do here.

Calls ListFile()

const getData = async () => {
    try {
        const response = await ListFile();
        const data = response.json();
        console.log(data);
    } catch (err) {
        console.log("getData error: "   err);
    }
}

getData(); //always returns getData error: TypeError: undefined is not an object (evaluating 'response.json')

ListFile()

async function ListFile() {
    // Reference Firebase Container
    var filesInStorageList = [];
    let content = [];
    const listRef = ref(fbStorage, filePath);
    console.log("Listing Files");


    // List all files in container
    listAll(listRef)
        .then((res) => {
            res.prefixes.forEach((folderRef) => {
                // All the prefixes under listRef.
                // You may call listAll() recursively on them.
                console.log(res);
            });
            res.items.forEach((itemRef) => {
                // All the items under listRef.
                let fileInStorage = itemRef["_location"]["path_"].slice(filePath.length);
                filesInStorageList.push(fileInStorage);
                // CORRECT DATA IS LOGGED console.log("Pushing "   fileInStorage);
                // CORRECT DATA IS LOGGED console.log(filesInStorageList);
            });

            return filesInStorageList;
        }).catch((error) => {
            // Uh-oh, an error occurred!
            console.log("ListFile - ERROR");
        });
}

CodePudding user response:

You're mixing async/await and Promises. Although they serve similar purposes, generally they are used separately to avoid situations like this where they are used together and then create unexpected results if one doesn't know what to look for.

You annotate your ListFile function with async, which means that it's expecting to find await somewhere. Instead, you use a Promise-based .then and .catch.

To convert your code, you could change it to this:

async function ListFile() {
    // Reference Firebase Container
    var filesInStorageList = [];
    let content = [];
    const listRef = ref(fbStorage, filePath);
    console.log("Listing Files");

    // List all files in container
    try {
      const res = await listAll(listRef);
      //...do your forEach loops
      return filesInStorageList;
    } catch(err) {
      //handle your error
    }
}

CodePudding user response:

You should add a return on the listAll method to return its value when calling it from getData(). See sample code below:

  const getData = async () => {
      try {
          ListFile()
          .then((response) => {
            // do something here.
            console.log(response);
          });

      } catch (err) {
          console.log("getData error: "   err);
      }
  }
  
  getData();

  async function ListFile() {
    // Reference Firebase Container
    var filesInStorageList = [];
    let content = [];
    const filePath = "test/";
    const listRef = ref(storage, filePath);

    // List all files in container
    return listAll(listRef)
        .then((res) => {
            res.prefixes.forEach((folderRef) => {
                // All the prefixes under listRef.
                // You may call listAll() recursively on them.
                console.log(res);
            });
            res.items.forEach((itemRef) => {
                // All the items under listRef.
                let fileInStorage = itemRef["_location"]["path_"].slice(filePath.length);
                filesInStorageList.push(fileInStorage);
                // CORRECT DATA IS LOGGED console.log("Pushing "   fileInStorage);
                // CORRECT DATA IS LOGGED console.log(filesInStorageList);
                // console.log(filesInStorageList);
                
            });

            return filesInStorageList;
        }).catch((error) => {
            // Uh-oh, an error occurred!
            console.log(error);
        });
}

Also, as @jnpdx stated, you have to use a Promise-based .then and .catch on your ListFile()

  • Related