From d91bec3c171e764a7cac7530ff9527ab672b6d76 Mon Sep 17 00:00:00 2001 From: Piotr Date: Mon, 16 Sep 2024 22:39:21 +0200 Subject: [PATCH 1/2] Added functionality to handel user input --- src/app/app.component.ts | 50 +++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 04b15b094..d2617da10 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,7 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from "@angular/core"; import { combineLatest, + debounceTime, filter, forkJoin, map, @@ -8,13 +9,13 @@ import { Subject, Subscription, switchMap, -} from 'rxjs'; -import { MockDataService } from './mock-data.service'; +} from "rxjs"; +import { MockDataService } from "./mock-data.service"; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], + selector: "app-root", + templateUrl: "./app.component.html", + styleUrls: ["./app.component.scss"], }) export class AppComponent implements OnInit, OnDestroy { searchTermByCharacters = new Subject(); @@ -34,7 +35,7 @@ export class AppComponent implements OnInit, OnDestroy { // 1.1. Add functionality to changeCharactersInput method. Changes searchTermByCharacters Subject value on input change. const inputValue: string = element.target.value; // YOUR CODE STARTS HERE - + this.searchTermByCharacters.next(inputValue); // YOUR CODE ENDS HERE } @@ -45,18 +46,26 @@ export class AppComponent implements OnInit, OnDestroy { // 3. Add debounce to prevent API calls until user stop typing. - this.charactersResults$ = this.searchTermByCharacters - .pipe - // YOUR CODE STARTS HERE - - // YOUR CODE ENDS HERE - (); + this.charactersResults$ = this.searchTermByCharacters.pipe( + debounceTime(300), // 3. Add debounce to prevent API calls until user stop typing. + filter((input: string) => input.length >= 3), // 2. Do not call API until user enters at least 3 chars. + switchMap((input: string) => this.mockDataService.getCharacters(input)) // 1.2. API call to get characters + ); } loadCharactersAndPlanet(): void { // 4. On clicking the button 'Load Characters And Planets', it is necessary to process two requests and combine the results of both requests into one result array. As a result, a list with the names of the characters and the names of the planets is displayed on the screen. // Your code should looks like this: this.planetAndCharactersResults$ = /* Your code */ // YOUR CODE STARTS HERE + this.planetAndCharactersResults$ = forkJoin([ + this.mockDataService.getCharacters(), // Get characters + this.mockDataService.getPlanets(), // Get planets + ]).pipe( + switchMap(([characters, planets]) => { + // Combine both arrays into one result list + return [...characters, ...planets]; + }) + ); // YOUR CODE ENDS HERE } @@ -67,12 +76,27 @@ export class AppComponent implements OnInit, OnDestroy { - Subscribe to changes - Check the received value using the areAllValuesTrue function and pass them to the isLoading variable. */ // YOUR CODE STARTS HERE + const characterLoader$ = this.mockDataService.getCharactersLoader(); + const planetLoader$ = this.mockDataService.getPlanetLoader(); + + const loadingSubscription = combineLatest([ + characterLoader$, + planetLoader$, + ]).subscribe(([isCharactersLoading, isPlanetsLoading]) => { + this.isLoading = this.areAllValuesTrue([ + isCharactersLoading, + isPlanetsLoading, + ]); // Check if both are loading + }); + + this.subscriptions.push(loadingSubscription); // Add to the subscriptions array // YOUR CODE ENDS HERE } ngOnDestroy(): void { // 5.2 Unsubscribe from all subscriptions // YOUR CODE STARTS HERE + this.subscriptions.forEach((subscription) => subscription.unsubscribe()); // YOUR CODE ENDS HERE } From 32f3a9e73dbab894824fde9cc46a3e7d333edec0 Mon Sep 17 00:00:00 2001 From: Piotr Date: Thu, 19 Sep 2024 19:13:30 +0200 Subject: [PATCH 2/2] Changed gitignore --- .gitignore | 1 + angular.json | 3 +++ src/app/app.component.ts | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index eecc05b70..960970349 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ yarn-debug.log* yarn-error.log* .idea/ +.angular/cache diff --git a/angular.json b/angular.json index 9faee94f5..c3cd06e39 100644 --- a/angular.json +++ b/angular.json @@ -76,5 +76,8 @@ } } } + }, + "cli": { + "analytics": false } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index d2617da10..7ec2e7602 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,13 +1,17 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { + // pobiera najbardziej aktualne dane, laczy je i wysyla do obserwtora jak tablice combineLatest, + // opóźnia wywołanie funkcji o podany czas debounceTime, filter, + // pozwala na pobranie danych z kilku źródeł. Wynik zwraca, dopiero gdy dane zostaną pobrane wszystkich strumieni danych. forkJoin, - map, Observable, + // Do subjecta można się zasubskrybować, ale jednocześnie udostępnia nam on też metody obserwatora (next/error/complete) Subject, Subscription, + // emituje wartości wewnętrznego Observable, ale każda nowa wartość emitowana przez strumień źródłowy powoduje anulowanie poprzedniego wewnętrznego Observable i utworzenie nowego switchMap, } from "rxjs"; import { MockDataService } from "./mock-data.service";