Skip to content

Instantly share code, notes, and snippets.

@codediodeio
Last active August 9, 2019 10:23
Show Gist options
  • Save codediodeio/32b2bcf96e2428c88cc305b86e112ef2 to your computer and use it in GitHub Desktop.
Save codediodeio/32b2bcf96e2428c88cc305b86e112ef2 to your computer and use it in GitHub Desktop.
Infinite scroll solution for Firebase + Angular4 (work in progress)
// Movies in Database
//
// movies
// movieKey
// title
// image
// year
import { Injectable } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
@Injectable()
export class MovieService {
constructor(private db: AngularFireDatabase) { }
getMovies(limit, key?) {
let query = {
orderByKey: true,
limitToFirst: limit,
}
if (key) query['startAt'] = key
return this.db.list('/movies', {
query
})
}
}
<h1>Movies</h1>
<div *ngFor="let movie of movies | async">
<h3>{{ movie?.title }}</h3>
<p>{{ movie?.year }}</p>
<img [src]="movie?.image" width="100px">
</div>
import { Component, OnInit, HostListener, ElementRef } from '@angular/core';
import { MovieService } from '../movie.service'
import { BehaviorSubject } from 'rxjs/BehaviorSubject'
import * as _ from 'lodash'
@Component({
selector: 'movies-list',
templateUrl: './movies-list.component.html',
styleUrls: ['./movies-list.component.scss']
})
export class MoviesListComponent implements OnInit {
movies = new BehaviorSubject([]);
batch = 2 // size of each query
lastKey = '' // key to offset from
ready = true // ready to fire new query?
finished = false // end of list to prevent duplicate queries
constructor(private movieService: MovieService, public el: ElementRef) { }
ngOnInit() {
this.combineMovies()
}
getMoreMovies() {
this.combineMovies(this.lastKey)
}
private combineMovies(lastKey?) {
this.ready = false
if (this.finished) return
this.movieService
.getMovies(this.batch+1, lastKey)
.do(movies => {
console.log(movies)
let batchLastKey = _.last(movies)['$key']
console.log(this.lastKey || 'none', batchLastKey)
if (batchLastKey == this.lastKey) {
this.finished = true
}
this.lastKey = batchLastKey
})
.map(movies => _.slice(movies, 0, this.batch) )
// .take(1)
.subscribe(movies => {
// if (this.finished) return;
let current = this.movies.getValue()
this.movies.next( _.concat(current, movies) )
this.ready = true
})
}
@HostListener('window:scroll', ['$event'])
checkScroll(e) {
const componentPosition = this.el.nativeElement.offsetTop
const scrollPosition = window.pageYOffset
if (scrollPosition >= componentPosition && !this.finished && this.ready) {
this.getMoreMovies()
}
}
}
@will-abule
Copy link

will-abule commented Dec 5, 2017

how can i use it in cloud fireStore and angular 5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment