I'm Trying to do a search to filter posts in a blog
the posts are got from the ngrx store as an observable
so when the user changes the value of the input the posts (with async pipe) will be updated by a pipe called filter-posts
and if the new array is empty a message should appear 'no posts found'
the problem is that the message is not shown after changing the input value
this is the code:
posts.component.html:
<div class="posts">
<!--search-->
<input
[(ngModel)]="searchValue"
class="p-2 rounded border w-100 bg-secondary text-light" type="search"
placeholder="Search..." id="search">
<!--posts-->
<ng-container *ngIf="(posts | async).length > 0; else noPosts">
<div class="post" *ngFor="let post of posts | async | filterPosts:searchValue">
<div class="p-title">
<a (click)="goTo('blog/posts/' + post.id.toString(), post)">{{post.title}}</a>
</div>
<div class="p-image">
<img [src]="post.imageSrc" [alt]="post.title">
</div>
<div class="p-cont">
{{post.content | slice:0:80}}
</div>
<div class="p-category">
<a *ngFor="let category of post.categories" class="p-1 m-1 text-light fw-bold">{{category}}</a>
</div>
<div class="p-date">
{{post.date}}
</div>
<app-author class="p-author d-block" [author]="post.author"></app-author>
</div>
</ng-container>
<ng-template #noPosts>
<div class="bg-danger w-100">No Posts Found</div>
</ng-template>
</div>
posts.component.ts:
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Router } from '@angular/router';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { Post } from 'src/app/models/post';
import { User } from 'src/app/models/user';
import { setSelectedPostId } from 'src/app/state/posts/actions';
import { getPosts, PostState } from 'src/app/state/posts/reducer';
import { getUserById } from 'src/app/state/users/reducer';
@Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.scss']
})
export class PostsComponent {
constructor(private store: Store<PostState>, private router: Router) { }
search = faSearch;
searchValue: string = '';
goTo(path: string, post: Post) {
this.router.navigate([path]);
this.setSelectedPost(post.id);
}
setSelectedPost(id: string) {
this.store.dispatch(setSelectedPostId({id}));
}
getUser(id: string): Observable<User> {
return this.store.select(getUserById(id));
}
posts: Observable<Post[]> = this.store.select(getPosts);
}
filter-posts.pipe.ts:
import { Pipe, PipeTransform } from '@angular/core';
import { Post } from '../models/post';
@Pipe({
name: 'filterPosts',
pure: false
})
export class FilterPostsPipe implements PipeTransform {
transform(value: Post[], searchValue: string): Post[] {
return value.filter(
(post) =>
post.title.toLowerCase().includes(searchValue.toLowerCase()) ||
post.content.toLowerCase().includes(searchValue.toLowerCase()) ||
post.author.name.toLowerCase().includes(searchValue.toLowerCase()) ||
post.categories.includes(searchValue.toLowerCase())
);
}
}