Reputation: 328
I have searched a lot on this but cannot understand how to get updated data from database. I am learning angular 2 and my situation is that I am fetching the data from table named branches using php in angular 2. Here is my Service in angular 2 project
import { Injectable } from '@angular/core';
import {Http, Headers, Response} from "@angular/http";
import "rxjs/add/operator/map";
import "rxjs/add/operator/catch";
import "rxjs/add/observable/throw";
import { Observable } from "rxjs/Observable";
@Injectable()
export class BranchesService {
constructor(private _http: Http){}
_errorHandler(error: Response){
console.error(error);
return Observable.throw(error || "Internal server error");
}
getBranches(limit, offset){
console.log("I am called");
return this._http.get("http://localhost/churchDb/api/v1/branches/"+limit+"/"+offset)
.map((response: Response) => response.json())
.catch(this._errorHandler);
}
updateBranch(value){
let headers = new Headers();
headers.append("Content-Type","application/json; charset=utf-8");
return this._http.post("http://localhost/churchDb/api/v1/update-branch", value , headers )
.map((response: Response) =>
response.json()
)
.catch(this._errorHandler);
}
}
And in my branches Component I am subscribing to getBranches in branches service
branches=[];
ngOnInit() {
this.branches=[];
this.sub=this._branchesService.getBranches(this.limit,this.offset)
.subscribe(
(resBranchesData)=> {
this.errorMsg=resBranchesData.message;
this.branches=resBranchesData.data;
console.log("Updated : " + JSON.stringify(resBranchesData));
},
(resBranchesError)=>{
console.log(resBranchesError)
}
);
}
And displaying branches in my View
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Address</th>
<th>City</th>
<th>Actions</th>
<!--<th>Username</th>-->
</tr>
</thead>
<tbody *ngFor="let branch of branches" style="text-align: left">
<tr>
<td>{{ branch.id }}</td>
<td>{{ branch.name }}</td>
<td>{{ branch.address }}</td>
<div *ngFor="let city of cities">
<td *ngIf="city.id == branch.city" style="border:none">
{{ city.name }}
</td>
</div>
<td><button class="btn btn-default" (click)="edit(branch)" >edit</button><button class="btn btn-danger" (click)="openModal()" style="margin-left: 10px">delete</button></td>
</tr>
</tbody>
</table>
On clicking edit I display a pre-filed form in modal in the same view
<modal [animation]="animation" [keyboard]="keyboard" [backdrop]="backdrop" [cssClass]="cssClass" #modal>
<form #branchEditForm="ngForm" (ngSubmit)="updateBranch(branchEditForm.value)">
<modal-header [show-close]="true">
<h4 class="modal-title">Add Church Branch</h4>
</modal-header>
<modal-body>
<div class="form-group">
<input type="hidden" class="form-control" required name="id" id="id" ngModel="{{branch.id}}">
<label>Church Name</label>
<input type="text" class="form-control" required name="name" id="name" ngModel="{{branch.name}}">
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" required name="address" id="address" ngModel="{{branch.address}}">
</div>
<div class="form-group">
<label>Address</label>
<select class="form-control" name="city" ngModel="{{branch.city}}">
<option *ngFor="let city of cities" value="{{city.id}}" [attr.selected]="city.id == branch.city ? '' : selected" >{{city.name}}</option>
</select>
</div>
</modal-body>
<modal-footer>
<button type="button" class="btn btn-default" data-dismiss="modal" (click)="modal.dismiss()">Cancel</button>
<!--<button type="button" class="btn btn-primary" [disabled]="!modalForm.valid" (click)="validationModal.close()">Update</button>-->
<input type="submit" class="btn btn-primary" [disabled]="!branchEditForm.valid" value="Update" />
</modal-footer>
</form>
</modal>
Upon submitting the form in branches Component
updateBranch(value:any){
console.log(value);
this._branchesService.updateBranch(value)
.subscribe(
(response)=>{
if(response.code == "200"){
this.modal.close();
this._router.navigate(['branches']);
}else{
// this.showFlag=true;
// this.loadingFlag=false;
// this.error=response.message;
}
},
(error) =>{ this.error=error }
)
}
The above function successfully updates the data in database table but I cant get the updated data in branches Service. I see the updated data only after clearing the cache of my browser. I have also tried navigating from a different component with no luck. I have also figured if the url in post request is changed, it gets me updated data. What am I doing wrong? I am new to angular 2 and cannot figure the reason. Any help is much appreciated.
Upvotes: 2
Views: 10141
Reputation: 8478
There are two ways to achieve this.
updateBranch
service.This means, in your server-side api call, return the updated list from the database, so that every time you call your update service, the updated list is returned:
this._branchesService.updateBranch(value)
.subscribe(
(response) => {
this.modal.close();
//this will only work if your server return the updated list.
this.branches=response.data;
})
Suggestion: You do not need to check the response.code
anywhere in your service or component, if you are using observables. Angular2 automatically wraps any response status code in between 200 to 300 as error, and you can handle them at .error()
.flatMap()
to get the updated list, right after update.In the event you have no control over the API implementation, aka they can't give you the response directly in the update
service, then you will need to manually call getBranches
again right after the update.
So what you can do is you use a .flatMap()
. flatMap will wait for the previous Observables to finish executing, and then proceed to execute the next one (think .then()
in promise):
updateBranch(value: any) {
this._branchesService.updateBranch(value)
.flatMap((response) => {
if (response.code == "200") {
this.modal.close();
return this._branchesServcice.getBranches(this.limit, this.offset);
} else {
// this.showFlag=true;
// this.loadingFlag=false;
// this.error=response.message;
//return Observable.empty if fails
return Observable.empty();
}
}
)
.subscribe((resBranchesData)=>{
//do whatever you want after retrieving the branches
})
}
Upvotes: 1
Reputation: 2774
I am not fixing your code, instead I'm showing you the principles. Consider this:
Service method:
updateBranch(branch: IBranch): Observable<IBranch> {
return this.http.post(this.YOUR_URL, branch)
.map(resp => resp.json() as IBranch);
}
updateBranch method will return an observable of IBranch type (you can also use "any" if you want, without using the interface) On your server side of course, you need to send back the updated model in the json format. This data will be mapped to the IBranch model (or any) once the request is done.
IBranch interface:
interface IBranch {
Id: number;
Name: string;
Address: string;
}
IBranch Component model:
branchModel: IBranch;
Now when you subscribe to the updateBranch method, updated model that server returned will be assigned to your branchModel.
Component's update method:
updateBranch(branch: IBranch): void {
this.branchService.updateBranch(branch)
.subscribe(response => this.branchModel = response);
}
Upvotes: 2