0

I'm trying to filter an array of strings from db firebase by clicking on button and calling method to filter. My problem is that nothing is happening.

What am I doing wrong ?

service

images: Observable<any[]>;

  constructor(private db: AngularFireDatabase) {
   this.images = this.db.list("/images").valueChanges();

  }

component

images: Observable<any[]>;

  constructor(private firebase: FirebaseService) {
    this.images = firebase.images;

  }

  loadImages(category: string) {
    return this.images.subscribe(x => x.filter(x => x === category))
  }

html

<button (click)="loadImages(image1)" >Filter</button>
  <div *ngFor="let image of images | async">
    <h2>{{image}}</h2>

  </div>

firebase db:

[image1, image2, image3, image4] - only for test

3 Answers 3

1

You can use an Observable with the map operator to display the data. Refer to this stackblitz, I replaced the database retrieval with an Observable containing an array of strings for demonstration purposes:

https://stackblitz.com/edit/load-and-filter-from-service

service:

retrieveImages(): Observable<any> {
  // replace with firebase call this.db.list("/images").valueChanges();
  return of(['image1', 'image2', 'image3', 'image4']);
}

component:

public images$: Observable<any>;

constructor(private firebase: FirebaseService) {
  ;
}

ngOnInit() {
  this.loadImages('image1');
}

loadImages(category: string) {
  this.images$ = this.firebase.retrieveImages().pipe(
    map(x => x.filter(x => x === category))
  );
}

html:

<button (click)="loadImages('image1')" >Filter 1</button>
<button (click)="loadImages('image2')" >Filter 2</button>
<button (click)="loadImages('image3')" >Filter 3</button>
<button (click)="loadImages('image4')" >Filter 4</button>
<div *ngFor="let image of (images$ | async)">
    <h2>{{image}}</h2>
</div>
Sign up to request clarification or add additional context in comments.

Comments

1

The issue is that if indeed you are trying to filter by whatever is in the string of category, a simple string comparison will always result in false. Take this for example.

const x = ['image1', 'image2', 'image3', 'image4'];
console.log(x.filter(x => x === 'image'));
// Resulting log will be an Array wtih length 0 because image1 !== image

However if you are looking for a substring of the string then you can see if the category is a substring of the string.

const x = ['image1', 'image2', 'image3', 'image4'];
console.log(x.filter(x => x.includes('image')));

Whether it is observable or not, the end result of your subscribe is the actual data, which you can run the filter on.

Comments

0

Instead of constructor method in service, you can create a new method which will return the image data.

Service:

getImages() {
    return this.db.list("/images").valueChanges();
}

In component, you can call the service method getImages().

1 Comment

try to set this to images: Observable<any[]>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.