Angular 2 call http before the user close the window

3.2k Views Asked by At

I want to save changes just before the user close the window, but it don't works when I quit the tab. I'm using router's canDeactivate method and it works when I refresh my page with F5, but when I close the tab datas are not saved. Here is my canDeactivate function in my component :

@HostListener('window:beforeunload')
canDeactivate(): Observable<boolean> | boolean {
    let subject = new Subject<boolean>();
    let observable = subject.asObservable();

    this.service.save(this.data).then(() => {
        subject.next(true);
    });

    return observable.first();
}

I already tried this too :

@HostListener('window:beforeunload')
canDeactivate(): Observable<boolean> | boolean {
    let xmlhttp = new XMLHttpRequest();   // new HttpRequest instance
    xmlhttp.withCredentials = false;
    xmlhttp.open("PUT", "http://localhost:8080/rest/api");
    xmlhttp.setRequestHeader("Content-Type", "application/json");
    xmlhttp.setRequestHeader("Accept", "application/json");
    xmlhttp.send(this.data);

    return false;
}
2

There are 2 best solutions below

12
On
@HostListener('window:beforeunload', ['$event'])
handler(event) {
  ...your warning
}

See it in action here link

1
On

The window:beforeunload is a synchronous event. If you perform an async action within the event listener the event will complete before your async action. That is why your http request is never made.

Unfortunately I could not find any method for forcing Angular 2's HTTP library to be performed synchronously. I was forced to import JQUERY and use AJAX.

                // the http call must be synchronous.
                // the 'unload' event won't wait for async
                // angular's http doesn't support synchronous requests
                // this is why we use JQUERY + AJAX
                $.ajax({
                    type: 'PUT',
                    async: false,
                    url: this.url
                });