Home > database >  Angular: Trying to use filter with use RXJS operators
Angular: Trying to use filter with use RXJS operators

Time:05-28

I have seedData I want to use the input button to search the existing data If I search with the data I have, I want it to show me otherwise, I want it written to me not found for example: enter image description here enter image description here

My interface:

export interface Post{
    id:number,
    date: Date,
    authorName:string,
    content:string;
}

My seedData in the database Service:

  export class PostDbService implements InMemoryDbService{
  
  constructor() { }
  createDb() {
    const posts: Post[] = [
      {id:1,authorName:"Daniel",content:"Amazon’s Garage Delivery Service"
      ,date:new Date('11/12/20')
    },
      {id:2,authorName:"Omer",content:"Jake From State Farm "
      ,date:new Date('12/20/21')},
      {id:3,authorName:"Lior",content:"The General"
      ,date:new Date('02/01/22')},
      {id:4,authorName:"Tomer",content:"Spotify’s Wrapped "
      ,date:new Date('11/11/20')},
    ];
    return {posts};
  }

my component html:

<input
  type="search"
  (input)="SearchPostsByName($event)"
  [(ngModel)]="authorName"
/>
<div *ngFor="let post of validPosts">
  <ng-container *ngIf="isExists">
    The name of the author is <b>{{ post?.authorName }}</b> with content
    <b>{{ post?.content }}</b> and released it on the date
    <b>{{ post?.date }}</b>
  </ng-container>
</div>
<br>

<form>
    <div>
        <label for="authorName">Author Name:</label>
        <br>
        <input [(ngModel)]="authorName" name="authorName" type="text" >
    </div>
    <div>
        <label for="content">Content:</label>
        <br>
        <input [(ngModel)]="content" name="content" type="text">
    </div>
    <div>
        <label for="date">Date:</label>
        <br>
        <input [(ngModel)]="date" name="date" type="date">
    </div>
    <div>
        <input type="button" value="Add posts" (click)="addPost()">
    </div>
</form>

my component.ts:

posts: Post[] = [];
   authorName = "";
   content = "";
   date = new Date();
   isExists = false;
   validPosts: Post[] = [];
   Search:string=''; 

  constructor(private postService: PostService) { }

  ngOnInit(): void {
    this.postService.getPosts().subscribe((posts)=> {
      this.posts = posts;
    });
  }
  addPost() {
    const post = {
      authorName: this.authorName,
      content: this.content,
      date: this.date,
      id: this.posts.length   1
    };
    this.postService.addPost(post).subscribe(()=> {
      this.postService.getPosts().subscribe((posts)=> {
        this.posts = posts;
        this.authorName = "";
        this.content = "";
        this.date = new Date();
      });
    });
    
  }

  SearchPostsByName($event : Event) {
    console.log($event);
    if (this.authorName) {
      this.validPosts = this.posts.filter((value) => value.authorName === this.authorName!); 
      if (this.validPosts.length > 0
      ) {
        console.log('found');
        this.isExists = true;
      } else {
        this.isExists = false;
      }
    }
  }

My Service:

export class PostService {

  private postsUrl = 'api/posts';

  constructor(private http: HttpClient) { }

  getPosts(): Observable<Post[]> {
    return this.http.get<Post[]>(this.postsUrl);
  }

  addPost(post: Post): Observable<Post> {
    let httpOptions = {
      headers: new HttpHeaders({'Content-Type':'application/json'})
    };
    
    return this.http.post<Post>(this.postsUrl, post, httpOptions)
  }

CodePudding user response:

Assign a second array of posts, and do the ng-for on that instead:

SearchPostsByName(authorName:string){
    this.filteredPosts = this.posts.filter(value => value.authorName === authorName);

    this.isExist = this.filteredPosts.length > 0;
    
  }

and in html loop on this one:

<input type="search" (input)="SearchPostsByName(authorName)">
<div *ngFor="let post of filteredPosts">  
      The name of the author is <b>{{post?.authorName}}</b> with content <b>{{post?.content}}</b>
      and released it on the date <b>{{post?.date}}</b>  
</div>
<div *ngIf="!isExist">Not found</div>

CodePudding user response:

Your function will never search the database as isExits is always false. As you do not share the complete component my best guess would be to try this:

https://stackblitz.com/edit/angular-ivy-pvmqnr?file=src/app/app.component.html

app.component.ts

import { Component, VERSION } from '@angular/core';

export interface Post {
  id: number;
  date: Date;
  authorName: string;
  content: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  // form variables
  authorName = '';
  content = '';
  date = new Date();

  // Array for Data
  posts: Post[] = [];

  // Array as result of filter
  validPosts: Post[] = [];
  searchName: string = '';

  // Boolean if author Exists
  isExist: boolean = false;

  constructor() {
    this.posts = this.createDb();
  }

  createDb() {
    const posts: Post[] = [
      {
        id: 1,
        authorName: 'Daniel',
        content: 'Amazon’s Garage Delivery Service',
        date: new Date(1408662000000),
      },
      {
        id: 2,
        authorName: 'Omer',
        content: 'Jake From State Farm ',
        date: new Date(1408662000000),
      },
      {
        id: 3,
        authorName: 'Lior',
        content: 'The General',
        date: new Date(1408662000000),
      },
      {
        id: 4,
        authorName: 'Tomer',
        content: 'Spotify’s Wrapped ',
        date: new Date(1408662000000),
      },
    ];
    return posts;
  }

  SearchPostsByName($event) {
    console.log($event);
    if (this.searchName) {
      this.validPosts = this.posts.filter(
        (value) => value.authorName === this.searchName!
      );
      if (this.validPosts.length > 0) {
        this.isExist = true;
      } else {
        this.isExist = false;
      }
    }
  }
  addPost() {
    const post = {
      authorName: this.authorName,
      content: this.content,
      date: this.date,
      id: this.posts.length   1,
    };
    this.posts.push(post);
    this.authorName = '';
    this.content = '';
    this.date = new Date();
  }
}

app.component.html

<label>Search Posts by Name </label>
<input
  type="search"
  (input)="SearchPostsByName($event)"
  [(ngModel)]="searchName"
/>
<div *ngFor="let post of validPosts">
  The name of the author is <b>{{ post?.authorName }}</b> with content
  <b>{{ post?.content }}</b> and released it on the date
  <b>{{ post?.date }}</b>
</div>
<div *ngIf="!isExist">
  <h3>No posts found</h3>
</div>

<hr />
<form>
  <div>
    <label for="authorName">Author Name:</label>
    <br />
    <input [(ngModel)]="authorName" name="authorName" type="text" />
  </div>
  <div>
    <label for="content">Content:</label>
    <br />
    <input [(ngModel)]="content" name="content" type="text" />
  </div>
  <div>
    <label for="date">Date:</label>
    <br />
    <input [(ngModel)]="date" name="date" type="date" />
  </div>
  <div>
    <input type="button" value="Add posts" (click)="addPost()" />
  </div>
</form>

  • Related