I have created success alerts, which is displayed after successfully editing or deleting the post, but there is one issue. When I perform the operation, click the 'back' button and open another post, the alert message still remains displayed until I click 'X' close button. I know that it can be solved through changing the alert status after clicking 'back' but I wonder if there is a better solution. For example, creating an observable to display the alerts, and unsubscribing it at the end of each function. What do you think, how should I solve this?
Here is my component.ts file:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormService } from './forms.service';
import { HttpClient } from '@angular/common/http';
import { alert } from './alert';
@Component({
selector: 'app-forms',
templateUrl: './forms.component.html',
styleUrls: ['./forms.component.css']
})
export class FormsComponent implements OnInit {
alert: alert;
id: any;
posts: any;
constructor(public formService: FormService ,private route: ActivatedRoute,
private router: Router, private http: HttpClient) { }
ngOnInit() {
this.id=this.route.snapshot.params['id'];
this.alert = new alert();
this.posts = this.formService.getForms(this.id).subscribe(
(forms: any) => {
this.formService.form = forms[0];
}
);
}
editPost() {
this.formService.editForm()
.then((res:any) => {
this.formService.alert.setAlert("Post has been successfully saved !");
})
}
deletePost() {
this.formService.deleteForm()
.subscribe(
data => {
console.log("DELETE Request is successful ", data);
this.formService.alert.setAlert("Post has been successfully deleted !");
},
error => {
console.log("Error", error);
}
)
}
}
Here is my service.ts file:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { form } from './form-interface';
import { alert } from './alert';
@Injectable({
providedIn: 'root'
})
export class FormService {
formsUrl = "https://jsonplaceholder.typicode.com/posts";
form: form = {
id: 0,
userId: 0,
title: '',
body: ''
};
alert: alert;
constructor(private http: HttpClient) {
this.alert = new alert();
}
getForms(id) {
return this.http.get('https://jsonplaceholder.typicode.com/posts'
+ "?id=" + id)
}
editForm() {
return fetch(this.formsUrl + "/" + this.form.id, {
method: 'PUT',
body: JSON.stringify(this.form),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
}
deleteForm() {
return this.http.delete(this.formsUrl + "/" + this.form.id);
}
}
Here is my alert.ts file:
export class alert{
"status" : boolean;
"text": string;
constructor(){
this.status=false;
this.text="";
}
public setAlert(text){
this.status = true;
this.text = text;
}
public close(){
this.status = false;
}
}
And here is my html file:
<div class="container">
<a class="btn btn-primary pull-right" routerLink = '/posts' >
Back
</a>
</div>
<div class="container">
<h2>Edit:</h2>
</div>
<div class="forms container">
<form #postForm="ngForm">
<div class="form-group">
<label for="title">Title</label>
<input [(ngModel)]="formService.form.title"
name="title"
id="title"
type="text"
class="form-control"
>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea [(ngModel)]="formService.form.body"
name= "body"
id="body"
cols="30"
rows="10"
class="form-control"
></textarea>
</div>
<button class="btn btn-success" (click) = "editPost()">Save</button>
<button class="btn btn-danger pull-right" (click) = "deletePost()">Delete</button>
<div class="container mt-4">
<div class="row">
<div class="col">
<div *ngIf = "formService.alert.status" class="alert alert-success
alert-dismissible fade show" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"
(click) = "formService.alert.close()">
<span aria-hidden="true">×</span>
</button>
{{formService.alert.text}}
</div>
</div>
</div>
</div>
</form>
</div>
If you want to wipe the alert dialog whenever you click somewhere, I'd suggest you to add an observable to listen the click
event on your document
. Don't forget to inject ElementRef
in your class constructor, and proper imports for takeWhile
, Subscription
, BehaviorSubject
, and Observable
. You might need to use pipe
regarding your rxjs version.
private alertOpened$ = new BehaviorSubject(false); // your alert is closed by default
private isOpenedSubscription: Subscription;
private clickSubscription: Subscription;
private isAlive = true; // auto unsubscribe
public ngOnInit() {
this.isOpenedSubsscription = this.alertOpened$
.takeWhile(() => this.isAlive)
.subscribe((isAlertOpened) => {
if (!isAlertOpened && this.clickSubscription) {
this.clickSubscription.unsubscribe();
}
this.clickSubscription = Observable.fromEvent(document, 'click')
.takeWhile(() => this.isAlive)
.subscribe((event: MouseEvent) => {
if (!this.elemRef.nativeElement.contains(event.target)) {
this.formService.setAlert(null);
this.alertOpened$.next(false);
}
});
});
}
public ngOnDestroy() {
this.isAlive = false;
}
editPost() {
this.formService.editForm()
.then((res:any) => {
this.alertOpened$.next(true);
this.formService.alert.setAlert("Post has been successfully saved !");
})
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.