0
var getListings = function () {
    listingsRef.once("value").then(function(snapshot) {
        console.log(snapshot.val());
    }, function (errorObject) {
        console.log("The read failed: " + errorObject.code);
    });
};

I have the following method. console.log(snapshot.val()) is working as expected. However, if I return snapshot.val() it returns undefined. I cannot seem to figure out how to do var currentSnapshot = getListings()

VDog
  • 1,083
  • 2
  • 13
  • 35
  • Typing from my phone, but I wonder if you declare a variable at the very top of the get Listings function, then set it equal to snapshot.val inside your other function, THEN return that variable at the very end of get Listings, if that would work. It would be important to make sure the return was outside of the nested function BTW – Dan Zuzevich Oct 06 '16 at 05:38
  • The usual pattern is to return the promise. Not exactly sure of promise implementation in firebase. – sabithpocker Oct 06 '16 at 05:42
  • @DanielZuzevich nah, this is the first thing I tried, this returns an empty string or undefined, because it's loading asynchronously, and I'm assigning the variable to nothing right away >_>. – VDog Oct 06 '16 at 05:54
  • Terrifying. I'll see if I can pull something together. Was just doing this in React with firebase. Granted it's a different result your looking for. – Dan Zuzevich Oct 06 '16 at 06:03
  • yoooo, peep one of my questions i had answered on firebase a few weeks ago. Never know, this might come up in your other pursuits. http://stackoverflow.com/questions/39600061/react-firebase-undefined-using-click-event – Dan Zuzevich Oct 06 '16 at 07:03

3 Answers3

3

Return a Promise from get listing. Consume the Promise using resolve and reject functions.

var getListings = function () {
    return listingsRef.once("value");
};

var currentSnapshot;

function loadListing(){
    getListings().then(setListing, showError);
}

function setListing(snapshot){
    currentSnapshot = snapshot.val()
}

function showError(e){
    console.log(e);
}

function init(){
    loadListing();
}

The other solution is the older way of using callbacks. This is not recommended as it can lead to unmanageable code if there are multiple nested async calls. Promises are a solution to the mess created by callbacks.

var currentSnapshot;
function getListings() {
    listingsRef.once("value", setListing, showError);
};

function setListing(snapshot){
    currentSnapshot = snapshot.val()
}

function showError(e){
    console.log(e);
}

function init(){
    getListings();
}
sabithpocker
  • 15,274
  • 1
  • 42
  • 75
1
  var getListings = function () {
    return listingsRef.once("value").then(function(snapshot) {
        return snapshot.val();
    }, function (errorObject) {
        console.log("The read failed: " + errorObject.code);
    });
};

Does this sorcery work at all?

Dan Zuzevich
  • 3,651
  • 3
  • 26
  • 39
  • this has the same issue that I have with what I posted (not in question). it loads it AFTER. It says "object value at left was snapshotted when logged", in my case an empty array, in yours a promise object, with an empty promisevalue, and then it says "value below was evaluated just now", in my case, it's exactly what I want, in your case, it's a promise object, with promisevalue containing what I want. Progress.... sort of? – VDog Oct 06 '16 at 06:37
  • ay yay yay. I am trying to get good with firebase too. So did that other guys answer work? – Dan Zuzevich Oct 06 '16 at 06:40
  • I'd rather not use promises, I'd prefer to use callbacks. And I want getListings(...) to return either the object in json, or an array of all the objects :( – VDog Oct 06 '16 at 06:42
  • Yeah, firebase documentation is first class garbage, when it actually comes to providing useful information like this. – Dan Zuzevich Oct 06 '16 at 06:43
  • http://stackoverflow.com/questions/23429203/weird-behavior-with-objects-console-log – Dan Zuzevich Oct 06 '16 at 06:44
  • This pattern usually works with promises. You get `snapshot.val()` instead of `snapshot` in the `resolve`. Possible when `once` and `then` return promises. Consume as `getLinsting().then(function(snapshotVALUE){/*no need for val()*/})` – sabithpocker Oct 06 '16 at 06:44
  • ughh I don't understand why we can't just have a function that returns the object of all items... – VDog Oct 06 '16 at 06:47
  • @sabithpocker sorry didn't see that, you mind updating your answer to have runnable code that either returns an array or object :D – VDog Oct 06 '16 at 06:47
  • would like to see this. will go into my javascript flash drive saved scripts hall of fame. – Dan Zuzevich Oct 06 '16 at 06:50
  • @VDog It is not possible to return actual result from an asynchronous call. Two solutions exist, callbacks and promises. [Reason explained here elaborately](http://stackoverflow.com/a/14220323/427146) – sabithpocker Oct 06 '16 at 06:50
  • Could you show how to do this with callbacks then? I just simply don't understand. I'm definitely trying to though. – VDog Oct 06 '16 at 06:54
  • That was a delicious description of callbacks and promises @sabithpocker – Dan Zuzevich Oct 06 '16 at 06:56
  • im going to bed but expect to see a beautiful rendition of a call back staring me in the face in the morning. peace out fellas. o_O – Dan Zuzevich Oct 06 '16 at 06:58
  • yeah @sabithpocker that was a great link! – VDog Oct 06 '16 at 07:05
0

nevermind, this for some reason doesn't work either... although it should?

var getListings = function () {
    var currentItems = [];
    listingsRef.on("value", function(snapshot) {
        currentItems.push(snapshot.val());
    })
    , function (errorObject) {
        console.log("The read failed: " + errorObject.code);
    };

    return currentItems;
};
VDog
  • 1,083
  • 2
  • 13
  • 35