diff --git a/frontend/src/angular/src/app/actors/actors.component.ts b/frontend/src/angular/src/app/actors/actors.component.ts index 25b2169..59efa71 100644 --- a/frontend/src/angular/src/app/actors/actors.component.ts +++ b/frontend/src/angular/src/app/actors/actors.component.ts @@ -9,7 +9,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Component, OnInit } from "@angular/core"; +import { Component, DestroyRef, OnInit, inject } from "@angular/core"; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from "@angular/router"; import { Actor, Gender } from "../model/actor"; import { QueryParam } from "../model/common"; @@ -25,6 +26,7 @@ export class ActorsComponent implements OnInit { protected actor: Actor = null; protected backParam = QueryParam.Empty; protected queryParam = QueryParam; + private readonly destroy: DestroyRef = inject(DestroyRef); constructor( private route: ActivatedRoute, @@ -34,6 +36,7 @@ export class ActorsComponent implements OnInit { public ngOnInit() { this.actorService .findActorById(Number(this.route.snapshot.paramMap.get("id"))) + .pipe(takeUntilDestroyed(this.destroy)) .subscribe((actor) => (this.actor = actor)); this.backParam = !this.route.snapshot.queryParams?.back ? QueryParam.Empty diff --git a/frontend/src/angular/src/app/filter-actors/filter-actors.component.ts b/frontend/src/angular/src/app/filter-actors/filter-actors.component.ts index 02b3ff0..39e7962 100644 --- a/frontend/src/angular/src/app/filter-actors/filter-actors.component.ts +++ b/frontend/src/angular/src/app/filter-actors/filter-actors.component.ts @@ -10,7 +10,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Component, OnInit } from "@angular/core"; +import { Component, DestroyRef, OnInit, inject } from "@angular/core"; import { Router } from "@angular/router"; import { NgbDateStruct, @@ -22,6 +22,7 @@ import { Actor, Gender } from "../model/actor"; import { ActorFilterCriteria } from "../model/actor-filter-criteria"; import { QueryParam } from "../model/common"; import { ActorsService } from "../services/actors.service"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @Component({ selector: "app-filter-actors", @@ -36,6 +37,7 @@ export class FilterActorsComponent implements OnInit { protected ngbBirthdayTo: NgbDateStruct; protected closeResult = ""; protected filterCriteria = new ActorFilterCriteria(); + private readonly destroy: DestroyRef = inject(DestroyRef); constructor( private actorsService: ActorsService, @@ -112,7 +114,7 @@ export class FilterActorsComponent implements OnInit { .searchPhrase.otherWordsInPhrase ? 0 : this.filterCriteria.searchPhrase.otherWordsInPhrase; - this.actorsService.findActorsByCriteria(this.filterCriteria).subscribe({ + this.actorsService.findActorsByCriteria(this.filterCriteria).pipe(takeUntilDestroyed(this.destroy)).subscribe({ next: (result) => (this.filteredActors = result), error: (failed) => { console.log(failed); diff --git a/frontend/src/angular/src/app/filter-movies/filter-movies.component.ts b/frontend/src/angular/src/app/filter-movies/filter-movies.component.ts index b00d46d..f07d0f4 100644 --- a/frontend/src/angular/src/app/filter-movies/filter-movies.component.ts +++ b/frontend/src/angular/src/app/filter-movies/filter-movies.component.ts @@ -10,7 +10,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Component, OnInit } from "@angular/core"; +import { Component, DestroyRef, OnInit, inject } from "@angular/core"; import { Router } from "@angular/router"; import { NgbDateStruct, @@ -23,6 +23,7 @@ import { Genere } from "../model/genere"; import { Movie } from "../model/movie"; import { MoviesService } from "../services/movies.service"; import { QueryParam } from "../model/common"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @Component({ selector: "app-filter-movies", @@ -38,6 +39,7 @@ export class FilterMoviesComponent implements OnInit { protected filterCriteria = new MovieFilterCriteria(); protected ngbReleaseFrom: NgbDateStruct; protected ngbReleaseTo: NgbDateStruct; + private readonly destroy: DestroyRef = inject(DestroyRef); constructor( private offcanvasService: NgbOffcanvas, @@ -97,7 +99,7 @@ export class FilterMoviesComponent implements OnInit { .searchPhrase.otherWordsInPhrase ? 0 : this.filterCriteria.searchPhrase.otherWordsInPhrase; - this.movieService.findMoviesByCriteria(this.filterCriteria).subscribe({ + this.movieService.findMoviesByCriteria(this.filterCriteria).pipe(takeUntilDestroyed(this.destroy)).subscribe({ next: (result) => (this.filteredMovies = result), error: (failed) => { console.log(failed); diff --git a/frontend/src/angular/src/app/login/login.component.ts b/frontend/src/angular/src/app/login/login.component.ts index 548791e..3bfd11e 100644 --- a/frontend/src/angular/src/app/login/login.component.ts +++ b/frontend/src/angular/src/app/login/login.component.ts @@ -10,10 +10,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Component, OnInit, EventEmitter, Output } from "@angular/core"; +import { Component, OnInit, EventEmitter, Output, DestroyRef, inject } from "@angular/core"; import { UsersService } from "../services/users.service"; import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { TokenService } from "ngx-simple-charts/base-service"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; enum ControlName { LoginName = "loginName", @@ -42,6 +43,7 @@ export class LoginComponent implements OnInit { protected modalMsgType = MessageType.Error; protected tillNextLogin = 0; protected waitingForResponse = false; + private readonly destroy: DestroyRef = inject(DestroyRef); constructor( private userService: UsersService, @@ -94,7 +96,7 @@ export class LoginComponent implements OnInit { .login( this.loginFormGroup.controls[ControlName.LoginName].value, this.loginFormGroup.controls[ControlName.Password].value - ) + ).pipe(takeUntilDestroyed(this.destroy)) .subscribe((myTillNextLogin: number) => { const res = myTillNextLogin <= 0; this.tillNextLogin = myTillNextLogin; @@ -122,7 +124,7 @@ export class LoginComponent implements OnInit { this.loginFormGroup.controls[ControlName.LoginName].value, this.loginFormGroup.controls[ControlName.Password].value, this.loginFormGroup.controls[ControlName.MovieDbKey].value - ) + ).pipe(takeUntilDestroyed(this.destroy)) .subscribe((res: boolean) => { this.cancelUser(); this.modalMsgType = res ? MessageType.Info : MessageType.Error; diff --git a/frontend/src/angular/src/app/movie-import/movie-import.component.ts b/frontend/src/angular/src/app/movie-import/movie-import.component.ts index 2dd5f5c..5fa79df 100644 --- a/frontend/src/angular/src/app/movie-import/movie-import.component.ts +++ b/frontend/src/angular/src/app/movie-import/movie-import.component.ts @@ -10,11 +10,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Component, OnInit } from "@angular/core"; +import { Component, DestroyRef, OnInit, inject } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; import { QueryParam } from "../model/common"; import { Movie } from "../model/movie"; import { MoviesService } from "../services/movies.service"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; enum ImportState { Idle = "idle", @@ -33,6 +34,8 @@ export class MovieImportComponent implements OnInit { protected ImportState = ImportState; protected importState = ImportState.Idle; protected importMovies: Movie[] = []; + private readonly destroy: DestroyRef = inject(DestroyRef); + constructor( private moviesService: MoviesService, @@ -58,7 +61,7 @@ export class MovieImportComponent implements OnInit { } private loadMatchingMovies(movieTitle: string) { - this.moviesService.importMovieByTitle(movieTitle).subscribe((m) => { + this.moviesService.importMovieByTitle(movieTitle).pipe(takeUntilDestroyed(this.destroy)).subscribe((m) => { this.importMovies = this.addNums(m); this.importState = ImportState.Idle; }); @@ -68,7 +71,7 @@ export class MovieImportComponent implements OnInit { this.importState = ImportState.Importing; this.importMovies = []; this.moviesService - .importMovieByMovieDbId(movie.movie_id) + .importMovieByMovieDbId(movie.movie_id).pipe(takeUntilDestroyed(this.destroy)) .subscribe((imported) => { this.importState = imported ? ImportState.ImportSuccess diff --git a/frontend/src/angular/src/app/movies/movies.component.ts b/frontend/src/angular/src/app/movies/movies.component.ts index 803d7ab..428a3a7 100644 --- a/frontend/src/angular/src/app/movies/movies.component.ts +++ b/frontend/src/angular/src/app/movies/movies.component.ts @@ -10,11 +10,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Component, OnInit } from "@angular/core"; +import { Component, DestroyRef, OnInit, inject } from "@angular/core"; import { MoviesService } from "../services/movies.service"; import { ActivatedRoute, Router } from "@angular/router"; import { Movie } from "../model/movie"; import { QueryParam } from "../model/common"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @Component({ selector: "app-movies", @@ -26,6 +27,7 @@ export class MoviesComponent implements OnInit { protected delMovie = false; protected backParam = QueryParam.Empty; protected queryParam = QueryParam; + private readonly destroy: DestroyRef = inject(DestroyRef); constructor( private route: ActivatedRoute, @@ -47,7 +49,7 @@ export class MoviesComponent implements OnInit { "delete movie id: " + this.movie.id + " title: " + this.movie.title ); this.delMovie = true; - this.movieService.deleteMovieById(this.movie.id).subscribe((result) => { + this.movieService.deleteMovieById(this.movie.id).pipe(takeUntilDestroyed(this.destroy)).subscribe((result) => { this.delMovie = false; if (!result) { console.log("Delete of movie id: " + this.movie.id + " failed."); diff --git a/frontend/src/angular/src/app/search/search.component.ts b/frontend/src/angular/src/app/search/search.component.ts index 7a0e0cc..ef8e46c 100644 --- a/frontend/src/angular/src/app/search/search.component.ts +++ b/frontend/src/angular/src/app/search/search.component.ts @@ -17,6 +17,8 @@ import { ViewChild, ElementRef, AfterViewInit, + DestroyRef, + inject, } from "@angular/core"; import { Movie } from "../model/movie"; import { Actor } from "../model/actor"; @@ -36,6 +38,7 @@ import { import { ActivatedRoute, Router } from "@angular/router"; import { QueryParam } from "../model/common"; import { TokenService } from "ngx-simple-charts/base-service"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @Component({ selector: "app-search", @@ -62,6 +65,7 @@ export class SearchComponent implements OnInit, AfterViewInit { protected loading = false; protected allMoviesLoaded = false; private actorListOffset = 0; + private readonly destroy: DestroyRef = inject(DestroyRef); constructor( private actorService: ActorsService, @@ -101,7 +105,7 @@ export class SearchComponent implements OnInit, AfterViewInit { showGenere(id: number) { this.showMenu = false; this.moviesByGenLoading = true; - this.movieService.findMoviesByGenereId(id).subscribe((res) => { + this.movieService.findMoviesByGenereId(id).pipe(takeUntilDestroyed(this.destroy)).subscribe((res) => { this.moviesByGenere = res; this.moviesByGenLoading = false; }); @@ -129,7 +133,8 @@ export class SearchComponent implements OnInit, AfterViewInit { of([]) ) ), - tap(() => (this.actorsLoading = false)) + tap(() => (this.actorsLoading = false)), + takeUntilDestroyed(this.destroy) ); this.movies = this.movieTitle.valueChanges.pipe( debounceTime(400), @@ -144,10 +149,11 @@ export class SearchComponent implements OnInit, AfterViewInit { of([]) ) ), - tap(() => (this.moviesLoading = false)) + tap(() => (this.moviesLoading = false)), + takeUntilDestroyed(this.destroy) ); if (!!this.tokenService.userId) { - this.movieService.allGeneres().subscribe((res) => (this.generes = res)); + this.movieService.allGeneres().pipe(takeUntilDestroyed(this.destroy)).subscribe((res) => (this.generes = res)); } this.route.url.subscribe(() => { if (!!this.tokenService.userId) {