what happens if we does not subscribe to HttpClient request which return observables in angular
Asked Answered
W

4

14

I am new to Angular & typescript , trying to understand HttpClient, observables & subscribe

When i do this in a function of a component

console.log(this.http.get('assets/user.json'));

I am receiving an object but can not see any request going to https://localhost:4200/assets/user.json in debugger network while if i change code to

this.http.get('assets/userDetail.json').subscribe(data => this.user = { name:  data['name']});

I can see the network request hitting the required URL. why this is happening ? my understanding was this.http.get('assets/userDetail.json') will hit the url even if we does not subscribe to response data stream.

Woadwaxen answered 18/2, 2018 at 16:5 Comment(0)
C
39

To understand the matter it's good to know there are hot & cold observables - the cold need to be subscribed otherwise they're not fired, the hot are fired no matter if something is subscribed to them.

Angular's HttpClient returns a cold Observable, so it's not fired until subscribed. To be sure if an observable is hot or cold you need to check corresponding docs, see for example HttpClient.post:

Constructs an Observable which, when subscribed, will cause the configured POST request to be executed on the server.

An example of an Angular's hot observable is e.g. ActivatedRoute.params - how to use - you see there is no subscription.

The fact an observable is hot/cold has more consequences than just having or not having to subscribe:

  • when subscribing, you should also unsubscribe in some cases to avoid memory leaks plus there is Angular's async pipe, which manages subscription for you; there is an article on the matter: Don't forget to unsubscribe (Angular specific)

  • there is a perfect article by Ben Lesh on the subject from a general point of view: Hot vs Cold Observables (not specific to Angular).

Chelyabinsk answered 18/2, 2018 at 16:24 Comment(2)
Really complete answer, +1Abby
would be great to have an option to make the respective call hotHemispheroid
P
1

It's worth to mention that assuming code like that and cold observable:

(pseudo-code)

Component:

ngOnInit(): void {
    console.log('Before, in ngInit')
    usersService.usersGet();
    console.log('After, in ngInit')
}

Service:

public usersGet(){
   console.log("I'm in service");
   let data = this.http.get('assets/user.json')
   console.log("I'm already here")
   return data;
}

you will see such ouput in dev tools in browser:

enter image description here

but your backend endpoint will not receive any request.

your backend will get request thought when you will change code to:

ngOnInit(): void {
    console.log('Before, in ngInit')
    usersService.usersGet().subscribe( x=> {
        console.log("I'm inside of subscribe")
        console.log(x)
    });
    console.log('After, in ngInit')
}

and output will be:

enter image description here

Papeete answered 4/3, 2020 at 19:37 Comment(0)
T
0

The previous answer already explained why it won't work without any subscribers. Because it's a cold observer, so it will be executed only when it found at least one subscriber.

So the alternative is basically:

 this.http.get('assets/user.json').subscribe();
Tokharian answered 22/11, 2018 at 9:43 Comment(0)
A
0

Overview: in this code snippet I create an webapi service using injectable that is visibile to the whole application. I subscribe to the observable returned by http.get from the callling function. The result of IView is bound to the data list similar to a promise. Now the WebApiService can be injected in other components constructor.

myComponent.component.ts

 public data: IDataView[];

Call the observable. this.app.getMyViews('123').subscribe(result=>{this.data=result;});

WebApi.service.ts

@Injectable({ providedIn: 'root' })

export class WebApiService
{
   constructor(private http: HttpClient,private env:             EnvironmentUrlService) {     }

getMyViews(id)
    {
        var path = this.env.urlAddress + '/my_class/GetData/'+id;
        return this.http.get<IDataView[]>(path);

  }

}

Apomorphine answered 24/8, 2020 at 21:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.