Issue
product-generic.service.ts
constructor(
private genericParaBirimi: GenericService<ParaBirimi, 0>,
) {
//#region List
this.genericParaBirimi?.Get_All("ParaBirimis/Generic_Method").subscribe((x: any) => this.paraBirims = x);
}
first-price-list.component.ts
constructor(
public productservice : ProductService) { }
this.genericParaBirimi?.Post(this.ParaBirimForm.value, "ParaBirimis/Generic_Method").subscribe({
next: (data) => { },
error: (err) => { },
complete: () => {
Refresh parabirims in html
}
});
first-price-list.component.html
<p-autoComplete formControlName="ParaBirimiID" [suggestions]="filteredParaBirimi"
(completeMethod)="filterParaBirims($event)" field="paraBirim" [dropdown]="true">
<div *ngFor="let item of productservice.paraBirims" class="country-item">
<div>{{item.paraBirim}}</div>
</div>
</p-autoComplete>
How can I use a method to automatically update the page without refreshing the page after adding to the parabirims list?
Solution
The first things we need to do is keep the paraBirimi state contained in the service. By design, you shouldn't be calling API requests from any components.
The next thing is to package your GET and POST updates into a single observable that components can subscribe to. Let's get into the code.
Service File
public paraBirimis$: Observable<ParaBirimi[]>;
private addParaBirimi = new Subject<ParaBirimi>();
constructor(private http:HttpClient){
this.paraBirimis$ = this.http
.get<ParaBirimi[]>(`${environment.url}/ParaBirimis/Generic_Method`)
.pipe(
switchMap(api => this.paraBirimiUpdate.pipe(
scan((list, new)=>[...list, new], api),
startWith(api)
)),
);
}
public postParaBirimi(payload) {
this.http
.post<ParaBirimi[]>(`${environment.url}/ParaBirimis/Generic_Method`, payload)
.pipe(
tap(newParaBirimi=>this.addParaBirimi.next(newParaBirimi))
).subscribe();
}
Our public observable paraBirimis$ first gets data from the GET endpoint. Then we switchMap into a Subject which will emit any new paraBirimi that are created from our POST request. The scan() operator is similar to .reduce(), but for values emitted from observables. https://www.learnrxjs.io/learn-rxjs/operators/transformation/scan In short, we're taking values emitted from our Subject, and adding them to our state array via the spread operator.
Because Subjects do not emit anything to begin with, we include the startWith() operator to have it emit our GET API request as the first value.
Next, we need our Subject to emit new values after POST requests. We create a public method that triggers our POST request, and then use .next() so the Subject will emit that new value, triggering the switchMap() in our public observable.
With the reactive pipeline setup in our service, our components can be quite simple, as our observables will automatically update any state mutations. The only new thing we need to include is a method that calls postParaBirimi() in our service.
Component TS
this.paraBirims$ = this.productservice.paraBirims$;
public postParaBirimi(){
this.productservice.postParaBirimi(this.ParaBirimForm.value);
}
Component HTML
<p-autoComplete
formControlName="ParaBirimiID"
[suggestions]="filteredParaBirimi"
(completeMethod)="filterParaBirims($event)"
field="paraBirim"
[dropdown]="true"
>
<div *ngFor="let item of paraBirims$ | async" class="country-item">
<div>{{item.paraBirim}}</div>
</div>
</p-autoComplete>
And that's it. You component has one active subscription to the observable we created in our service. Invoking the POST event in our service will cause that same observable to emit a new list with the newly created value.
Answered By - Joshua McCarthy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.