I have header search icon which shows small popup of input and button on click. If user searches for any input then I am redirecting user to results page. I have separate component for header and search results. I am passing search input with common service from header to search result.
This works fine for first time. When I enter new text and search then nothing happens. It does not pass search input to search result component and also does not load search result again.
header template html
<a
#closeSearchForm
href="#"
data-title="Search"
id="dropdownMenuButton1"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
><img src="assets/images/icons/search.png" alt=""
/></a>
<span >Search</span>
<div
aria-labelledby="dropdownMenuButton1"
>
<form [formGroup]="searchForm" (ngSubmit)="onSubmitSearch()">
<div >
<div >
<input
type="text"
placeholder="Search here...."
formControlName="searchInput"
[ngClass]="{ error_border: submitted1 && sf.searchInput.errors }"
/>
<div *ngIf="submitted1 && sf.searchInput.errors" >
<div *ngIf="sf.searchInput.errors.required">Search text is required</div>
</div>
</div>
<div >
<button type="submit">
Search</button>
</div>
</div>
</form>
</div>
header ts code
onSubmitSearch() {
this.submitted1 = true;
if (this.searchForm.invalid) {
this.loading1 = false;
return;
}
this.loading1 = true;
if (this.sf.searchInput.value) {
this.closeSearchForm.nativeElement.click();
var searchValue = this.sf.searchInput.value;
// this.searchForm.reset();
// Object.keys(this.searchForm.controls).forEach(key => {
// this.searchForm.get(key).setErrors(null) ;
// });
this.commonModelService.data = searchValue;
this.router.navigate(['search-results']);
}
}
common model service code - for passing search input
import { Injectable } from '@angular/core';
@Injectable()
export class CommonModelService{
data:any
}
search result component ts
ngOnInit(): void {
this.searchValue = this.commonModelService.data;
this.getSearchResults(); <!-- this function will call api and show data in html -->
}
I am not getting what is going wrong. Right now its working only for first time. Search should work any time with any input given by user.
What will be the best solution to pass search input from header component to search component and achieve search functionality working any time , on any page, with any new inputs when user tries to search?
Please help and guide. Thanks
CodePudding user response:
If you are already on the search result, you redirect code will not re-render the component and without re-render your search.result.component-> ngOninit
will not fire and load the result.
Instead of passing data directly you should your observable and Behaviour subject.
search result component ts
ngOnInit(): void {
this.commonModelService.search$.subscribe((searchInput) => {
if(searchInput !=== undefined){ // we want to capture empty string
this.getSearchResults()
}
})
}
common model service code - for passing search input
import { Injectable } from '@angular/core';
public search$ = new BehaviorSubject(undefined) // if undefined initially we don't do anything.
@Injectable()
export class CommonModelService{
data:any
}
BehavourSubect will return the last event value when its subscribe the first time and in subsequent case, when you are already at the page it will push value like regular subject. Advice: also remove the subscribe every time on OnDistory
this.commonModelService.search.next(searchValue);
this.router.navigate(['search-results']);