Calling forEach on Dictionary in Node.js

465 views Asked by At

I am trying to loop over a Firebase reference. It works but for some reason the forEach loop runs one more time than there are objects in the reference. This causes the Promise.all() function to fail and the whole promise to fail. Here is my code. I have no Idea what I'm doing wrong.

return userReceiptMetrics.child(userID).child('postItemIDs').orderByChild('itemID').equalTo(oldProductID).once('value', function(oldSnapshot) {
            var oldPostItemIDs = [];
            var metrics = oldSnapshot.val()

            if (oldSnapshot.val() != null) {
                return Promise.all(oldSnapshot.forEach(function(record) {
                    console.log(record.val());
                    var oldKey = record.key;
                    var newKey = oldKey.replace(oldProductID, newProductID);
                    var data = record.val();
                    oldPostItemIDs.push(oldKey);
                    data.itemID = newProductID;
                    updateObject['userReceiptMetrics/'+userID+'/postItemIDs/'+newKey] = data;
                    updateObject['userReceiptMetrics/'+userID+'/postItemIDs/'+oldKey] = null;
                })).then(function() {
                    return Promise.all(oldPostItemIDs.map(function(oldPostItemID) {
                        return userReceiptMetrics.child(userID).child('postItems').child(oldPostItemID).then(function(oldPostItem) {
                            var oldKey = oldPostItem.key
                            var newKey = oldKey.replace(oldProductID, newProductID)
                            var data = record.val()                        
                            updateObject['userReceiptMetrics/'+userID+'/postItems/'+newKey] = data;
                            updateObject['userReceiptMetrics/'+userID+'/postItems/'+oldKey] = null;

                            progress(38);
                        });
                    }))
                }).catch(function(error) {
                    console.log('fudge louise');
                });
            }
        });

Here is the console output:

 App listening on port 8080
Press Ctrl+C to quit.
FIREBASE WARNING: Using an unspecified index. Consider adding ".indexOn": "_state" at /productUpdateQueue/tasks to your security rules for better performance 
FIREBASE WARNING: Using an unspecified index. Consider adding ".indexOn": "_state" at /productUpdateQueue/tasks to your security rules for better performance 
{ date: '2016-12-21 22:05:03',
  itemID: 'Macys-EReceipts-MENS HOSIERY-Size(No size provided)-Color(No color provided)-786888403743',
  postID: '-KZbmaThvxNmrvHwh_mc' }
{ date: '2016-12-21 22:05:03',
  itemID: 'Macys-EReceipts-MENS HOSIERY-Size(No size provided)-Color(No color provided)-786888403743',
  postID: '-KZbxAUcwzcP28C91EZA' }
FIREBASE WARNING: Using an unspecified index. Consider adding ".indexOn": "itemID" at /userReceiptMetrics/HeQST8hSkoPUmkBiVDR0tpSPo0x2/postItemIDs to your security rules for better performance 
fudge louise
1

There are 1 answers

0
WikipediaBrown On BEST ANSWER

So it looks like the Promise.all() call failed because there is an empty object at the end of the list of objects. Here is the corrected code.

return userReceiptMetrics.child(userID).child('postItemIDs').orderByChild('itemID').equalTo(oldProductID).once('value', function(oldSnapshot) {
            var oldPostItemIDs = [];
            var metrics = oldSnapshot.val()

            if (oldSnapshot.val() != null) {
                return Promise.all(oldSnapshot.forEach(function(record) {
                    console.log(record.val());
                    var oldKey = record.key;
                    var newKey = oldKey.replace(oldProductID, newProductID);
                    var data = record.val();
                    oldPostItemIDs.push(oldKey);
                    data.itemID = newProductID;
                    updateObject['userReceiptMetrics/'+userID+'/postItemIDs/'+newKey] = data;
                    updateObject['userReceiptMetrics/'+userID+'/postItemIDs/'+oldKey] = null;
                })).then(function() {
                    return oldPostItemIDs.map(function(oldPostItemID) {
                        return userReceiptMetrics.child(userID).child('postItems').child(oldPostItemID).then(function(oldPostItem) {
                            var oldKey = oldPostItem.key
                            var newKey = oldKey.replace(oldProductID, newProductID)
                            var data = record.val()                        
                            updateObject['userReceiptMetrics/'+userID+'/postItems/'+newKey] = data;
                            updateObject['userReceiptMetrics/'+userID+'/postItems/'+oldKey] = null;

                            progress(38);
                        });
                    })
                }).catch(function(error) {
                    console.log('fudge louise');
                });
            }
        });