Reputation: 427
I try to make search form for movie database with dropdown datalist with search results, and when click to option I want to move to movie page. But I can't figure out how to hide [value] string in <option [value]>. Here is my code:
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2"
required
list="foundMovies"
[(ngModel)]="searchString"
[ngModelOptions]="{standalone: true}"
(ngModelChange)="startSearch($event)"
type="search" placeholder="Search" aria-label="Search">
<datalist id="foundMovies">
<option *ngFor="let movie of foundMovies"
[value]="movie.id"
> {{movie.title}} </option>
</datalist>
<button
(click)="submitForm()"
class="btn btn-outline-success my-2 my-sm-0" >Найти</button>
</form>
and here is ts file:
import { Component, OnInit } from '@angular/core';
import {MovieService} from '../../../model/movie.service';
import {Movie} from '../../../model/movie';
@Component({
selector: 'app-movie-search-form',
templateUrl: './movie-search-form.component.html',
styleUrls: ['./movie-search-form.component.css']
})
export class MovieSearchFormComponent implements OnInit {
searchString: Movie;
foundMovies: Movie[];
constructor(private movieService: MovieService) { }
ngOnInit(): void {
}
submitForm(): void{
console.log(this.searchString);
}
startSearch(search): void {
console.log(search);
if (search.length >= 3) {
this.movieService.searchForMovies(search)
.subscribe(result => {
if (result.length){
this.foundMovies = result;
}
});
}
}
}
the main problen that when I use [ngValue] with options I can't get movie.id in startSearch(search): void {
console.log(search); string, I allways get the name of the movie, and if I use [value] instead I get movie.id when choose option, but I can't hide movie.id on dropdown list of options.
So the question is how to hide movie.id, when I use [value] with options, or how can I use [ngValue] such way, to get movie.id when I select some option.
Using [ngValue]
Upvotes: 1
Views: 1354
Reputation: 427
After an hours of lookup I found that usage of dataList is not a good solution in my case. So I found answer for my question here : enter link description here
Here is my input:
<form class="form-inline my-2 my-lg-0">
<input id="typeahead-prevent-manual-entry" type="text" class="form-control"
[(ngModel)]="movie"
[ngModelOptions]="{standalone: true}"
(ngModelChange)="jumpToMovie($event)"
[ngbTypeahead]="movieSearch"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
[editable]='false' />
<hr>
<pre>Model: {{ movie | json }}</pre>
<button
(click)="submitForm()"
class="btn btn-outline-success my-2 my-sm-0" >Search</button>
</form>
Also I have to add library "@ng-bootstrap/ng-bootstrap": "7.0.0",
And white movieSearch
and formatter
methods in ts:
import { Component, OnInit } from '@angular/core';
import {MovieService} from '../../../model/movie.service';
import {Movie} from '../../../model/movie';
import {Observable, of} from 'rxjs';
import {switchMap, catchError, map} from 'rxjs/operators';
import {debounceTime, distinctUntilChanged} from 'rxjs/operators';
@Component({
selector: 'app-movie-search-form',
templateUrl: './movie-search-form.component.html',
styleUrls: ['./movie-search-form.component.css']
})
export class MovieSearchFormComponent implements OnInit {
movie: Movie;
searchString: string;
foundMovies: Movie[];
constructor(private movieService: MovieService) { }
ngOnInit(): void {
}
submitForm(): void{
console.log(this.searchString);
}
formatter = (movie: Movie) => movie.title;
movieSearch = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
// switchMap allows returning an observable rather than maps array
switchMap( (searchText) => {
this.searchString = searchText;
return this.movieService.searchForMovies(searchText).pipe(
// Reduce size of result array
map( data => data.slice(0, 7 )
));
}),
catchError(err => '')
);
}
jumpToMovie(event): void{
console.log(event);
}
}
So now, when I click on suggested links this.movie becomes an object, and I can move to movie page I looked for.
Upvotes: 0
Reputation: 2367
Based on your code ( I recommend always specified the version of angular that you are running)
With the new line I put,now you have the id of the movie.
ts
import { Component, OnInit } from '@angular/core';
import {MovieService} from '../../../model/movie.service';
import {Movie} from '../../../model/movie';
@Component({
selector: 'app-movie-search-form',
templateUrl: './movie-search-form.component.html',
styleUrls: ['./movie-search-form.component.css']
})
export class MovieSearchFormComponent implements OnInit {
searchString: Movie;
foundMovies: Movie[];
constructor(private movieService: MovieService) { }
ngOnInit(): void {
}
submitForm(): void{
console.log(this.searchString);
}
startSearch(search): void {
idMovie: number = this.foundMovies.find(x => x.title === search)[0].id // WARNING NEW LINE
console.log(search);
if (search.length >= 3) {
this.movieService.searchForMovies(search)
.subscribe(result => {
if (result.length){
this.foundMovies = result;
}
});
}
}
Upvotes: 1