-1

I'm trying to return a value from a method. I have a nested function within the method which should return a value.

However, I can't seem to get it to return the value of title when calling traverseProjects().

Here's my code.

getTitle: function(userId, projectId) {
        u = new Firebase('<firebase.com>/users/' + userId + /projects/ + projectId);
        function traverseProjects() {
            u.once('value', function(snapshot) {
                if (snapshot.key() === projectId) {
                    var obj = snapshot.val();
                    var title = obj.details.title;
                }
                console.log(title);
                return title;
            });
        }

        var title = traverseProjects();
        console.log(title);
        return title;
    }
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Cole Roberts
  • 954
  • 3
  • 15
  • 25
  • 1
    Use `callback`...Values retrieved after asynchronous operation can not be returned as `return` statement is executed long back when the value was undefined.... – Rayon Feb 28 '16 at 04:11

1 Answers1

1

Do something like this:

getTitle: function(userId, projectId, callback) {
    u = new Firebase('<firebase.com>/users/' + userId + /projects/ + projectId);
    function traverseProjects(callack) {
        u.once('value', function(snapshot) {
            if (snapshot.key() === projectId) {
                var obj = snapshot.val();
                var title = obj.details.title;
            }
            console.log(title);
            callback(title);
        });
    }

    traverseProjects(function(title) {
      console.log(title);
      callback(title);
    });
}

And call the function with:

getTitle('uid', 'pid', function(title){
    console.log(title);
})

Like @felix-kling suggested, we can simply eliminate the inner function:

getTitle: function(userId, projectId, callback) {
    u = new Firebase('<firebase.com>/users/' + userId + /projects/ + projectId);
    u.once('value', function(snapshot) {
        if (snapshot.key() === projectId) {
            var obj = snapshot.val();
            var title = obj.details.title;
        }
        console.log(title);
        callback(title);
    });
}
Ben
  • 1,557
  • 13
  • 30
  • Don't really see the purpose of `traverseProjects` here, or why you do `return callback()` instead of `callback()`. Keep it simple! – Felix Kling Feb 28 '16 at 04:27
  • I see it as good coding style to explicitly return in every function, some people find it easier to read like this :) – Ben Feb 28 '16 at 04:28
  • I'd argue that it's more confusing when working with asynchronous methods, since it has no effect, but it could make the impression that it does. – Felix Kling Feb 28 '16 at 04:29
  • True traverseProjects is probably not needed, but for the purpose of the direct problem, I think it can be more clear if we demonstrate how the callback works without too much alteration to the original code. – Ben Feb 28 '16 at 04:29
  • I see, this might be a personal preference thing in the end – Ben Feb 28 '16 at 04:30
  • FWIW, you have some typos there, `callack` vs `callback`. – Felix Kling Feb 28 '16 at 04:31
  • @FelixKling nice call XD – Ben Feb 28 '16 at 04:33
  • One more reason to keep it simple :P – Felix Kling Feb 28 '16 at 04:34
  • @Ben please remove the return from `return callback(title);`. In a more strongly typed language the callback would be a void function and returning a value would be a compile time error. In JavaScript you return a value to a caller that isn't doing anything with it. That is confusing and will lead people to misunderstand your code. Confusing people who read your code is not a good coding style. – Frank van Puffelen Feb 28 '16 at 08:20