So I finally decided to catch up with the times and migrate some old angular Http
stuff to HttpClient
.
The app used to run on a bunch of Promise based code, which has since been removed (mostly).
My old Promise function looked something like this:
public getUser(profileId: number): Promise<User> {
return this.http.post("/api/url", postObject, HttpSettings.GetDefaultHttpRequestOptions());
.map(u => new User(u))
.catch(this.handleError)
.toPromise();
}
My new HttpClient function is much nicer:
public getUser(profileId: number): Observable<any> {
return this.http.post("/api/url", postObject, HttpSettings.GetDefaultHttpRequestOptions());
}
But what I don't like currently is that in each subscription to this, I now have to map the data to an instance of User...
service.getUser(1).subscribe(data => {
data = new User(data);
});
This is the simplest .map
which I have, some post methods actually return a rather complex object which map to many new object instances.
I see with HttpClient.get
you can Type assert the response, can I do something like this with .post
so that I don't have to map the data to a new User in each of the subscriptions?
Note: Eventually I will migrate this again to a better architecture where you actually subscribe to a User variable, but for now I just want to implement HttpClient.
The post method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. Essentially this means that the POST data will be stored by the server and usually will be processed by a server side application.
Before you can use HttpClient , you need to import the Angular HttpClientModule . Most apps do so in the root AppModule . You can then inject the HttpClient service as a dependency of an application class, as shown in the following ConfigService example.
HttpClient is one of the best APIs to make HTTP requests. It returns an Observable, but if you want to return a Promise that can also be done using HttpClient. It is best practice to return an Observable and subscribe it in other functions.
can I do something like this with .post so that I don't have to map the data to a new User in each of the subscriptions
<= Yes, the exact same generic to specify the return type is available for post
and also put
. It will not convert automatically to an object but you can specify an interface for the returned data. Alternatively you can chain map
in the service like you did previously but I recommend you use the pipeable operators.
Example using pipeable operators to mimic what you had in your previous code.
import { map } from 'rxjs/operators/map';
public getUser(profileId: number): Observable<User> {
return this.http.post("/api/url", postObject, HttpSettings.GetDefaultHttpRequestOptions())
.pipe(map(data => new User(data)));
}
Example where User
is nothing more than an interface with properties.
If the data itself is json representative of an interface that has properties you can convert it directly.
export interface User {
userId: number;
name: string;
}
public getUser(profileId: number): Observable<User> {
return this.http.post<User>("/api/url", postObject, HttpSettings.GetDefaultHttpRequestOptions());
}
If you import your User class in the service, you can map it back to a User
object by add <User>
after the post
and before the ()
public getUser(profileId: number): Observable<any> {
return this.http.post<User>("/api/url", postObject, HttpSettings.GetDefaultHttpRequestOptions());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With