2

I'm gonna do my best to explain this as I'm new to using javascript along with Firebase SDK. Here is the mock data I have:

    "Via" : {
    "00zz00" : {
      "coordinates" : "0,0",
      "order_number" : 1,
      "route_id" : "xyz987",
      "via_id" : "00zz00"
    },
    "1a2b3c" : {
      "coordinates" : "10,-10.1",
      "order_number" : 1,
      "route_id" : "abc123",
      "via_id" : "1a2b3c"
    },
    "2b3c4d" : {
      "coordinates" : "45.5,-24.7",
      "order_number" : 2,
      "route_id" : "abc123",
      "via_id" : "2b3c4d"
    },
    "3c4d5e" : {
      "coordinates" : "45.8,-24.0",
      "order_number" : 4,
      "route_id" : "abc123",
      "via_id" : "3c4d5e"
    },
    "4d5e6f" : {
      "coordinates" : "20.0,-20.0",
      "order_number" : 3,
      "route_id" : "abc123",
      "via_id" : "4d5e6f"
    }
  }

I first made a query using .on() with the "child_added" event to fill an array with the coordinates of every result:

var waypoints = new Array();
var refVia = firebase.database().ref("Via");
refVia
    .orderByChild("route_id")
    .equalTo("abc123")
    .on("child_added", function (snapshot) {
        waypoints.push(snapshot.val().coordinates);
    });

I am calling another API and using the array to create a route and I realized I was getting an error since my array was still empty. I found a solution on here mentioning using .once().then() with the "value" event along with a promise but I'm a bit confused about how to go from here. I tried this but I'm a bit lost from here.

var refVia = firebase.database().ref("Via");
    return refVia
        .orderByChild("route_id")
        .equalTo("abc123")
        .once("value")
        .then(
            function (snapshot) {
                var via = [];
                
                //Not sure what to do here to add the entries to my array...

                return Promise.all(via);

            },
            function (error) {
                
                console.error(error);
            }
        );
Brandon P.
  • 23
  • 5

1 Answers1

1

I understand that you need to iterate over the keys of the nodes (which are equal to the via_id subnode values) in order to define promises that you add to the via Array. So the following should do the trick:

  var refVia = firebase.database().ref('Via');
  return refVia
    .orderByChild('route_id')
    .equalTo('abc123')
    .once('value')
    .then((snapshot) => {
      const via = [];
      for (const [key, value] of Object.entries(snapshot.val())) {
        console.log(`${key}: ${value.via_id}`);
        via.push(*** here build the Promise based on the key value ***)

        // example with Axios https://github.com/axios/axios
        via.push(axios.get('https://..../via?ID=' + key));
      }
      
      return Promise.all(via);
    })
    .then(results => {
      // results is an Array of results of each call to the API
      // For example
      results.forEach(r => {
        // ...
      })
    })
    .catch((error) => {
      console.error(error);
    });
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • I will test this tomorrow since I am about to head out. If I understand correctly, I should be able to get the "coordinates" child values where I build the Promise? – Brandon P. May 19 '21 at 21:01
  • 1
    You need to pass an array of Promises to `Promise.all`. Since you call an API, you need to use a library like Axios or fetch to execute the calls and get back a Promise. Since you don't give details about the URL of the API it's difficult to help more. – Renaud Tarnec May 19 '21 at 21:07