How to implement Angular @defer @loading in the right way with Firestore Pagination

38 Views Asked by At

I have a lot of data objects, from Angular Firestore.

I want to load a size of 4, show them in the template. After scrolling to the last element using @defer (on viewport) {}, I want to load the next 4 items. During loading, I want to show a @loading or @placeholder.

my-component.component.html

@for (p of pagProjects; track $index) {
  @defer(on viewport) {
    <div style="height: 300px;"><pre>{{ p| json }}</pre></div>
  }
  @loading(after 100ms; minimum 1s) {
    <div>Loading</div>
  }
  @placeholder(minimum 1s) {
    <div>Placeholder</div>
  }
}

my-component.component.ts

export class MyComponent implements OnInit {
  pagProjects: Project[] = []
  lastVisible: any

  constructor(private firestore: Firestore) {}

  ngOnInit() {
    this.getProjects()
  }

  async getProjects() {
    const first = query(
      collection(this.firestore, 'projects'), 
      limit(4)
    );
    const documentSnapshots = await getDocs(first);

    this.pagProjects = documentSnapshots.docs.map(doc => doc.data() as Project);
    this.lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1];
  }

  async getNextProjects() {
    const next = query(
      collection(this.firestore, 'projects'),
      startAfter(this.lastVisible),
      limit(4)
    );
    const documentSnapshots = await getDocs(next);

    // Append the next set of projects to the existing projects
    // Correct??
    this.pagProjects = [...this.pagProjects, ...documentSnapshots.docs.map(doc => doc.data() as Project)];

    this.lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1];
  }

}

If you execute that code you'll see, that the pagination works with scrolling, but I don't see a @loading. What is the correct implementation of @defer with pagination?

0

There are 0 best solutions below