-1

I have already read the answers to the question How do I return the response from an asynchronous call? But I'm not sure I understood it well and I think that my problem is a bit different. I change my service in this way:

.service('CommonService',['$firebase', function($firebase){

var username;

function onComplete(result){
    username = result;
};

var getData = function(){

    var ref = new Firebase("https://instafame.firebaseio.com");

    ref.onAuth(function(authData){
        var userid = authData.uid;
        console.log(userid);

        var newref = new Firebase("https://instafame.firebaseio.com/users/" + userid)

        newref.once("value", function(snapshot) { 
            var data = snapshot.val()
            newUsername = data.username;
            callback(newUsername);

        })
    });
  };

    return{
        getUsername: function(){
            getData(onComplete);
            return username;}
    };
}])

In my controller I store inside a variable user the return of the CommonService:

var user = CommonService.getUsername();
console.log(user);

The problem is that the console still returns "undefined". I have tried to change the code following the suggestions but it doesn't run. What should I do?

Thanks in advance

Community
  • 1
  • 1
fabius
  • 55
  • 1
  • 8

1 Answers1

1

Async / Await

We need to provide a way to wait for a response from your requests. We can use async/await to do this and lets make a Promise to handle resolving the value we are retrieving;

.service('CommonService',['$firebase', function($firebase){

var username;
var getData = function(){     //declare this function as an async

    return new Promise((resolve, reject) => { 

        var ref = new Firebase("https://instafame.firebaseio.com");

        ref.onAuth(function(authData){
            var userid = authData.uid;
            console.log(userid);

            var newref = new Firebase("https://instafame.firebaseio.com/users/" + userid)

            newref.once("value", function(snapshot) { 
                var data = snapshot.val()
                newUsername = data.username;
                !!newUsername 
                    ?
                resolve(newUsername)
                    :
                reject('Error: No username found');
            })

       });
    };
 };

    return{
        getUsername: async function(){
            username = await getData(); //await will pause execution of the code here until getData() returns a value.
            return username;
        }
    };
}])
Rex
  • 376
  • 2
  • 11
  • You don't need to declare `getData` as `async` - it already explicitly returns a new Promise - but you need to do so at the `getUsername` function where you use `await`, so that it returns a promise as well. – Bergi Oct 11 '17 at 17:14
  • Currently, we cannot use await without first declaring the containing function as an async function. This might change in a the up coming ECMA update but until then, we need async for await. Also you can shorten the getUsername method to `getUsername: function(){ return await getData(); }` – Rex Oct 11 '17 at 17:33
  • Yes, exactly. And your code doesn't follow these rules - the function that contains `await` is not declared `async` – Bergi Oct 11 '17 at 17:55