We will add some more advanced behaviours
Code on github https://github.com/kendarorg/Angular101
Before this step you should follow the 2 part preparation
Should import the http client inside the app.module
import { HttpClientModule } from '@angular/common/http';
Adding it to the imports
imports: [
...
HttpClientModule,
],
Now we modify the data service adding the dependency from httpClient (of course importing HttpClient) and a variable with the base url for the api, with it we add the Observable and the Subject (or subscriber for observable). This is part of reactive Js (rxjs) and is needed to handle the notification of the result of the call to the services
import { HttpClient } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
...
baseUrl:string = 'http://localhost:4201/api/address';
constructor(private http: HttpClient) { }
Let's start with the getAddresses. It returns an Observable. NOT the result data but a promise to fulfill the request. Notice the return value added! (:Observable
public getAddresses():Observable<AddressElement>{
return this.http.get<AddressElement>(this.baseUrl);
}
We can remove the list of pre-filled addresses and the "clone" stuff.
Now that the return value of getAddresses is changed, we need to setup how the observable is handled. Inside the onIniti we need to give to subscribe with a callback (data:{}) to the promise. We know that the content will be an array of AddressElement thus it needs to be casted!
ngOnInit(): void {
this.dataService.getAddresses().subscribe((data: {}) => {
this.addresses = data as AddressElement[];
});
}
When the request of items will be completed, the addresses array will be filled
Now running (and filling) the REST server and running the app will let us see the list of items!
Let's change first the service. Notice the return value added! (:Observable
public getById(id:number):Observable<AddressElement>{
return this.http.get<AddressElement>(this.baseUrl+"/"+id);
}
And then the single-address.component.ts. Notice that we are still casting the item, and in case of a new item nothing is changed!
Another special thing is the initialization of an empty object. This is needed to have some "real" value shown before the REST call result.
ngOnInit(): void {
...
}else{
this.address = {} as AddressElement;
this.dataService.getById(this.addressId).subscribe((data: {}) => {
this.address = data as AddressElement;
});
}
}
Same goes for the cancel path
cancel(path:string){
...
}else{
this.dataService.getById(this.addressId).subscribe((data: {}) => {
this.address = data as AddressElement;
});
}
}
When a call to getById is made the system waits for the response and invoke the callback with a generic object passed, that is then cast to AddressElement
You can verify all of this editing an item, modifying it and canceling: the item will be put in the previous state
Another way to verify the behavior is adding a new item
Now the save and delete are missing
As before, inside the service. Notice the return value added! (:Observable
public save(item:AddressElement):Observable<AddressElement>{
this.http.post<AddressElement>(this.baseUrl,item);
}
A bit more has to be changed inside the controller. The whole part after the save() must be moved inside the callback!
save(userForm:NgForm, path:string){
if(!userForm.form.valid){
return;
}
this.dataService.save(this.address).subscribe((data: {}) => {
this.readonly=true;
if(this.addressId==-1){
this.router.navigateByUrl(path);
}
});
}