mvrc
October 6, 2016, 12:59pm
1
Hello,
I’m trying to do an ion-infinite-scroll with a FirebaseListObservable.
For this i have an Rx Subject in the query :
@Injectable()
export class Objects {
public objects: FirebaseListObservable<any[]>;
public nbObjects: Subject<any>;
public cpt: number;
constructor(public af: AngularFire, public platform: Platform) {
this.cpt = 20;
this.nbObjects = new Subject();
this.events = this.af.database.list('/objects', {
query: {
orderByChild: 'timestamp',
startAt: Date.now()/1000,
limitToFirst: this.nbObjects
}
});
this.platform.ready().then(() => {
this.nbObjects.next(this.cpt);
});
}
loadMoreObjects() : void {
this.cpt += 20;
this.nbObjects.next(this.cpt);
}
}
With this, i have the following function in my component :
doInfinite(infiniteScroll) {
this.objects.loadMoreObjects();
setTimeout(() => {
infiniteScroll.complete();
}, 3000);
}
But my problem is : How can i remove the timeout to listen updates on my FirebaseListObservable Object ? And is it possible to tell when there is no more objects to load ?
Is this a right approach ?
1 Like
mvrc
October 10, 2016, 4:20pm
2
And one last question :
When using the following code :
loadEvents(path: string) : void {
this.objects = this.af.database
.list(path, {
query: {
orderByChild: 'timestamp',
startAt: Date.now()/1000,
limitToFirst: this.nbObjects
}
})
.mergeMap((events) => {
return Observable.forkJoin(
events.map((event) => {
return this.af.database.object('/objects/'+event.$key).first();
}),
(...values) => {
events.forEach((event, index) => { event.event = values[index]; });
return events;
}
);
}) as FirebaseListObservable<any[]>;
setTimeout(() => { this.nbObjects.next(20); }, 200);
}
I have to put this.nbObjects.next(20); in a timeout and if i don’t, my html page won’t display any object of this.objects .
What’s wrong ? I cannot figure where the problem is exactly
mvrc
October 12, 2016, 5:30pm
3
Okay, I found a solution to listen at my FirebaseListObservable changes. But still have question.
I declare isLoading : Subject = new Subject(); and at the end of my forkJoin, just before return events; I add this.isLoading.next();.
Then, my ionInfiniteList function look like this :
doInfinite(infiniteScroll) {
this.provider.isLoading
.first()
.subscribe((x) => {
infiniteScroll.complete();
});
this.provider.loadMoreObjects();
}
I listen to one emit of my Observable isLoading, and then i complete infiniteScroll because i know the firebaseList have been updated.
With another little hack, i have been able to know when there is no more data :
I just add the following line just before return events; at the end of my forkJoin();
this.stillHaveObjects = (objects.length >= this.nbObjectsToDisplay);
But is this the right approach ? And how to remove my timeout (cf previous post ) ?
I was able to solve this using the Firebase SDK. Care to know how? Or you’re strictly using the AngularFire2?
DeeM52
December 11, 2016, 10:48pm
5
I am interested in knowing how.
Okay so to accomplish what he did. I did this:
In a provider: (event-data.ts)
getlimitedcategoryList(number): any {
return firebase.database().ref('/subjectList').limitToLast(number);
}
In my page: (home.ts)
var a = 15;
export class HomePage {
constructor(public eventData: EventData,) {
this.eventData.getlimitedcategoryList(b).on('value', snapshot => {
rawList10 = [];
snapshot.forEach(snap => {
rawList10.unshift({
id: snap.key,
subject: snap.val().subject,
sid: snap.val().sid
});
});
this.subjectsList = rawList10;
});
}
This is the class that increments variable “b”
loadmoresubjects(){
b+=5
this.eventData.getlimitedcategoryList(b).on('value', snapshot => {
let rawList1 = [];
snapshot.forEach(snap => {
rawList1.unshift({
id: snap.key,
subject: snap.val().subject,
sid: snap.val().sid
});
});
this.subjectsList = rawList1;
});
}
And home.html
<ion-item-divider>
Subjects
</ion-item-divider>
<div padding>
<ion-chip *ngFor="let subjects of subjectsList" (click)="presentFilteredAnswers(subjects.subject)">
<ion-icon name="pin"></ion-icon>
<ion-label>{{subjects?.subject}}</ion-label>
</ion-chip>
<ion-chip (click)="loadmoresubjects()">
<ion-icon name="pin"></ion-icon>
<ion-label>More..</ion-label>
</ion-chip>
</div>
4 Likes
mvrc
December 12, 2016, 8:52am
7
That’s a good one with unshift. But i have a vey different home.html where i’m using infiniteScrollList.
I will try with your solution, it seems easier to implement and understand.
yes. I’m more flexible with the Firebase SDK. So far I havent had to make any changes to my code I posted previously, works quite well.
Oh and to tell if there are no more objects to load… Hmm… I’ll get back to you with an example on that
naree
March 18, 2017, 6:58pm
10
@trevaun23 Love this solution.Much cleaner.
@mvrc Did you ever figure out how to get it working with infinite scrolling?
mvrc
March 19, 2017, 6:13pm
11
I’ve a workaround
<ion-infinite-scroll [hidden]="!activities.stillHaveEvents"
(ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content loadingSpinner="dots">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
doInfinite(infiniteScroll) {
this.activities.finishLoading
.first()
.subscribe(() => {
infiniteScroll.complete();
});
this.activities.loadMoreEvents();
}
and then in my mergeMap() :
public finishLoading: Subject<any>;
[...]
(...values) => {
events.forEach((event, index) => {event.event = values[index];});
this.stillHaveEvents = (events.length >= this.cptEventsToDisplay);
this.finishLoading.next();
return events;
}
2 Likes
Have you tried using a behaviour subject from rxjs library and emitting a new value on reaching the top of the chat list? Seems to work for me!
mvrc
March 27, 2017, 8:03am
13
Yes. This is exactly what i do but when i’m reaching the bottom of my list (this is not a chat here). This way i can “paginate” the query.
1 Like
Hello mvrc !! I need to create an infinite lazy scroll with Firebase. I found in the forum a post that you also need this solution. Did you do it? Do you mind sharing?
Thank you
mvrc
April 17, 2017, 9:12am
15
Hello @mvdurao .
I’ve just used the functions described above in this topic
@mvrc Thanks for sharing all this!
Can you define “this.cptEventsToDisplay” and “this.nbObjectsToDisplay”? Where are you setting those totals?