0
votes

I'm building a realtime masonry feed for images using Angularfire2 and Firebase. I've set a maxlimit to how many stories should be displayed in the html. The desired behavior: The data is received from firebase using angularfire2 to the frontend realtime (working). The data is kept in an array of objects, that is displayed in the html (working).
If new data received in the stream exceeds the limit (working), run a function to pop the last element in the array, and remove it from the database (not working). So assuming the limit is 5: If #6 object is observed, remove the last index from the array, while making #6 object the first obj in the array index.

Getting the data from a service:

public get curatedStoriesFromDB(): Observable<any> {
    const dbRef = this.db.list<any>(this.dbBaseRef,
      ref => ref.orderByChild('isMarked').equalTo(true).limitToLast(100));
    return dbRef.valueChanges();
  }

Returns me the observable, which im subscribing to in my feed component:

dbData = new BehaviorSubject<any>(null);
storiesData = this.dbData.asObservable();

const dbRef = this.dbSrv.curatedStoriesFromDB
  .pipe(catchError(err => of(err)))
  .subscribe((data) => {
    this.dbData.next(data);
    console.log(this.dbData.getValue())
    //the code to check if the limit is exceeded
    if (data.length > (this.maxStories + 2)) {
      console.log('Too many stories')
      this.resetArraySize(data);
    }
  })

And the limit function:

resetArraySize(stories: any[]) {
    const $stories = stories;
    while ($stories.length > (this.maxStories + 2)) {
      const shifted = $stories.pop();
      this.dbSrv.removeStoryFromFeed(shifted);
      this.dbData.next($stories)
    }
    return $stories;
  }

I'm unwrapping the data in my HTML component like so:

...*ngFor="let story of (storiesData | async); let i = index;" id={{i}};>
1

1 Answers

0
votes

The limit should be handled automatically by the .limitToLast(100) clause. The array you receive should not exceed that limit.

However, if you need finer grain control, consider using .stateChanges and handling the child_added, child_removed, and child_changed events. You will reduce the amount of data being transferred back and forth between your client and firebase.

angularfire2 list

Also, you are emitting this.dbData multiple times which may cause performance issues and cause confusion while debugging. First reduce the size of the array, then just emit it once.