1

I'm setting up a Framework7 project with webpack, and I want a module for database requests using Firebase. The function from the imported module runs, but the requested array is never returned/the promise doesn't resolve. What am I doing wrong?

I suspect that I'm either doing something wrong when importing the module itself, or I'm not resolving the promise properly. I've tried and failed with both return and resolve in the getAllRestaurants function in the module. I've tried waiting for the response from the database call with async/await, .then() and even with a setTimout. I've also tried just saying let array = database.getAllRestaurants().

database.js(module)

  // Initialize Firebase
  import firebase from 'firebase'
  import config from '../config';
  const firebaseApp = firebase.initializeApp(config);
  const db = firebase.firestore(firebaseApp);

//getting array form database

export function getAllRestaurants(){
    //defining db route omitted
    let array = [];
    route.get().then(function(querySnapshot){
        querySnapshot.docs.forEach(function(document){
            array.push(document.data());
        });
        return array; //Have tried with only return and with only resolve
    })
    .resolve(array)  //Have tried with only return and with only resolve
    .catch(function(error){
        console.error('error i firebase getallrestaurants: ', error);
    });
}
//The function getAllRestaurants works and gets the array just fine, so the error is in returning it to the function caller

app.js (main)

//importing my module
import * as database from './database';

//trying to return an array from a function in the module
let array = database.getAllRestaurants(); //returns undefined

//another attempt at getting the same array, .then never executes
database.getAllRestaurants().then((array =>{
  //do stuff
}));

I expected the code in app.js to get an array from the function, but it only gets 'undefined'

Magnus
  • 11
  • 2
  • Because `getAllRestaurants()` is based on an *asynchronous* operation (the database operation), you *cannot* simply return a value from it. You can however return a Promise, and have the client code expect that. – Pointy Apr 02 '19 at 13:44
  • None of your examples can work because the first case (let array one) is expeting a result like if the operation was synchronous. However, it's asynchronous and it's actually returning **nothing**. The second case expects a **promise** returned, but none is returned. You should **return a Promise** instead and handle the result **asynchronously**. – briosheje Apr 02 '19 at 13:46
  • I would expect that `return route.get().then( ... rest of code...` should work. Else there's something wrong with the route and specifically what `.resolve()` does to the result. Do you have docs about what exactly `.resolve()` will return? Is it part of Framework7 ? – Shilly Apr 02 '19 at 13:47

2 Answers2

1

There's no return statement in getAllRestaurants. Try

export function getAllRestaurants(){
    //defining db route omitted
    let array = [];
    return route.get().then(function(querySnapshot){

and skip this line:

    .resolve(array)  //Have tried with only return and with only resolve
mbojko
  • 13,503
  • 1
  • 16
  • 26
0

I would change your code to this:

export function getAllRestaurants(){
    // Return a new Promise, which will either resolve a value or reject an error.
    return new Promise(function(resolve, reject){
        //defining db route omitted
      let array = [];
      // Nothing changed here.
      route.get().then(function(querySnapshot){
          querySnapshot.docs.forEach(function(document){
              array.push(document.data());
          });
          resolve(array);
          // Replaced the below line with the one above.
          //return array; //Have tried with only return and with only resolve
      })
      // No need for the line below.
      // resolve(array)  //Have tried with only return and with only resolve
      .catch(function(error){
          console.error('error i firebase getallrestaurants: ', error);
          // Added a line here to reject the error.
          reject(error);
      });
    });
}

I've commented the edits above. In this way, you will always get a Promise out of that method, and you can use it in this way:

//importing my module
import * as database from './database';

database.getAllRestaurants().then(array =>{
  //do stuff
}).catch(err => {
   console.log('an error happened!');
});
briosheje
  • 7,356
  • 2
  • 32
  • 54