Skip to content

angular how to await subscribe

I am newbie regarding Angular applications. I don’t understand exactly how subscribe works. My current blocker is that I don’t understand why the console.log("B") is executed before the console.log("A"), consequently presenting the result of an empty array (see the links to console output).

I tried to put all the code in a function with async/await to wait for the function. I don’t understand why it doesn’t work.

What is the best way in this case to wait for a subscription?

The console.log("B") must be executed after the console.log("A").

this._roleService.getRoleTypes(this.token).subscribe(
    response => {
        if(response.status != "error" && response.code != 400){
            let _roleTypes:Array<RoleType> = new Array<RoleType>(); 
            _roleTypes = new Array<RoleType>();
            response.data.forEach(rt => {
                let roleType:RoleType = new RoleType(
                    rt.id,
                    rt.name
                );
                _roleTypes.push(roleType);
            });
            console.log("A");
            console.log(_roleTypes);
            this.roleTypes = _roleTypes;
        }
        else{
            this._loginService.destroySession();
        }
    },error => {
        this.errorMessage = <any>error;
        if(this.errorMessage != null){
            console.log(this.errorMessage);
            alert("Petition Error");
        }
    }
);
console.log("B");
console.log(this.roleTypes);

Answer

As you may know, subscriptions are used to handle async method call. Thus, the code inside the subscribe() method is executed only when the async method return its result (after a http call for instance).

While waiting for the async response, the program continues and execute the following code. That’s the goal of async calls!

That’s why your console.log('B') is executed before your console.log('A').

Here is an example:

this.myservice.asyncCall().subscribe( (result) => {
   // wait for the async response
   console.log('I get some data from asyncCall()');
});
// sync code executed, even if the previous async call doesn't respond anything
console.log('Code executed after the subscription. But not waiting for it to respond');

If you want you’re console.log('B'), you have to move it into your subscription function (after the else statement). You can also call a method from that location, depending on the purpose you’re looking for.

You may take a look at the .map() method as well. This allows you to edit the retrieved response before you handle it in the subscribe method (to add it some data, transform it, log or anything).