Quick update to Angular 7+.
Old version at https://github.com/audiBookning/autocomplete-search-angularfirebase2-5-plus/tree/original (ATTENTION: many packages are not updated and unsecures)
Refactoring of the code of 'Autocomplete Search With Angular4 and Firebase' at https://angularfirebase.com/lessons/autocomplete-search-with-angular4-and-firebase/ for AngularFire 2 (https://github.com/angular/angularfire2) version 5.+
Default project generated with:
- Angular CLI: 7.1.1
- Node: 10.12.0
- Angular: 7.1.0
- typescript: 3.1.6
- @angular/fire (angularfire2): 5.1.1
- firebase: 5.6.0
- rxjs: 6.3.3
Do not forget to add your Firebase Credentials in the file at .\src\app\firebase.credentials.ts
I tried to follow the original code the best i could, but some things had to be changed nonetheless.
-
movies.service.ts:- Added
start.switchMapto get the string value of theBehaviorSubject. I had some problems if used directly. - Used
snapshotChanges()instead ofvalueChanges()to keep the firebase key in the data by adding an extramapthat return a new object{ key: c.payload.key, ...c.payload.val() };Refer to https://github.com/angular/angularfire2/blob/master/docs/rtdb/lists.md for more info. - Added
.debounceTime(200)and.distinctUntilChanged()operators.debounceTime(200)to avoid to hit the database after every keypress, replacing the code in the chapter 'Preventing Multiple Queries to Firebase' of the article mentioned earlier.distinctUntilChanged()for the cases when, for ex, one type 'mov' wait for the observable to resolve then type 'movi' followed rapidly by deleting the last keypress getting 'mov' and avoiding another hit to firebase.
- Used the RxJs operator
BehaviorSubjectinstead ofSubjectto initialize the query on first load. - Corrected
getMoviesmethod to use only one argumentstartsinceendis directly dependent ofstart. One can avoid having 2BehaviorSubjectand having to use alternatively the RxJs operatorzipto synchronize them (See the answers in the article for an example of the use of thezipoperator).
- Added
-
movie-search.component.html(including also the changes inmovie-search.component.ts):- Changed the input to
#searchInput (keyup)="search(searchInput.value)- Added
#searchInputfollowing best practices from Get user input from a template reference variable (https://angular.io/guide/user-input#get-user-input-from-a-template-reference-variable) (keyup)instead of(keydown)because it was giving me some weird synchronization problems.- In this simple example, one could further simplify the code by replacing
(keyup)="search(searchInput.value)"with(keyup)="startAt.next(searchInput.value)"and deleting thesearch()method.
- Added
- Converted the
moviesarray to an observablemovies$and used theasyncpipe to follow some Reactive Programming best practices, simplifying the code and handling the unsubscription automatically
- Changed the input to
Autogenerated by Angular CLI:
This project was generated with Angular CLI version 7.1.1.
Run ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.
Run ng generate component component-name to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module.
Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.
Run ng test to execute the unit tests via Karma.
Run ng e2e to execute the end-to-end tests via Protractor.
To get more help on the Angular CLI use ng help or go check out the Angular CLI README.