Comments (7)
This can be down by using a .once()
call to get the initial set of data, and then subscribing to child_added
events.
const ref = new Firebase("<my-firebase-app>/list");
ref.once("value")
.then((data) => {
let initialArray = [];
data.forEach((item) => arr.push(item));
return initialArray;
})
.then((initialArray) => {
const lastKey = initialArray[initialArray.length - 1].key();
ref.orderByKey().startAt(lastKey).on("child_added", (snap) => initialArray.push(snap));
});
Wow. The new promises library makes that real nice.
from angularfire.
Hello? Update plz?
from angularfire.
Okay, after further thought and review, here is my proposal:
const ref = new Firebase('https://<my-firebase-app>/messages');
// helper function for placing the key on the object
const itemify = (snap) => {
let value = snap.val();
let item = {};
if (typeof value !== 'object') {
item.value = value;
} else {
item = snap.val();
}
item._key = snap.key();
return item;
};
ref.once('value')
// get the initial array one-time with once()
.then((snap) => {
let initialArray = [];
snap.forEach((child) => {
initialArray.push(itemify(child));
});
return initialArray;
})
.then((initialArray) => {
let initialLoad = false;
// get the last key in the initialArray
const lastKey = initialArray[initialArray.length - 1]._key;
// listen for children
// This is not data wasteful because the initial load fires
// from the cache, not from the network
ref.on('child_added', (child, prevKey) => {
// ignore children from the initial load
// was the previous child, the last item in the initial load?
if(prevKey === lastKey) {
initialLoad = true;
// loaded here
console.log(initialArray);
}
// If the initial load has completed, then add to the array
if (initialLoad === true) {
initialArray.push(itemify(child));
console.log(initialArray);
}
});
ref.on('child_removed', (child) => {
});
ref.on('child_changed', (child, prevKey) => {
});
});
from angularfire.
It seems like a reasonable approach to me.
Regarding the actual implementation, I would want to use Observable instead of promise, so that it will play nicely with the work I'm doing on interactive querying. Mostly, I want to make sure I can cancel the completion of the promise chain if the query has changed.
PromiseObservable.create(ref.once('value'))
.map(items => items.map(itemify)
.flatMap((initialArray) => {
return new FirebaseObservable(observer => {
let initialLoad = false;
const lastKey = initialArray[initialArray.length - 1]._key;
ref.on('child_added', (child, prevKey) => {
if(!initialLoad && prevKey === lastKey) {
initialLoad = true;
// loaded here
console.log(initialArray);
}
// If the initial load has completed, then add to the array
if (initialLoad === true) {
initialArray.push(itemify(child));
console.log(initialArray);
}
});
// Add other listeners
...
return () => ref.off();
});
});
We could obserblify the logic inside of flatMap
even further.
from angularfire.
This might be simpler if add values before "initial load" are treated the same as one after "initial load". To state this inversely, there is probably no reason for those two states to behave differently, and then there would be exactly one way to populate values into the array.
You can simply call the on('child-added'...) and have it push things to the array, and call once('value',...) after this. Now when once('value',...) is triggered, you know the "initial" data is all present (see event guarantees). At this point, you can trigger whatever code will cause the change detection to occur (such as fulfilling the promise perhaps?).
Even slightly more elegant, in my opinion, is abandoning the idea of initial load. It really is no different than any other time during the operation of the page (it's just a big influx of added events), so treat it the same and use a debounce to trigger the change detection event, so that UI renders are batched nicely.
I'd be a little more explicit, but I can't tell in the above how change detection is triggered or what effect pushing things into the array might be having behind the scenes (I assume pushing to the array is what triggers the multiple arrays being returned).
from angularfire.
@katowulf thanks for the idea. I think this would be the best strategy, and we could utilize observable operators to accomplish it pretty easily. We just have to think about the right strategy. I think we should implement #55 before implementing this, since it would make it easier.
@davideast I'll go ahead and unassign this unless you've started work on it.
from angularfire.
@jeffbcross I'm working on this and #73 since they are related.
from angularfire.
Related Issues (20)
- AngularFire 17.0.0 throwing errors with Angular 17.0.0 HOT 3
- feat: allow AngularFire to be used in a zoneless angular application HOT 14
- reauthenticateWithPhoneNumber throws auth/user-mismatch error HOT 1
- collectionData doesn't allow angular app to become stable with angular 17 and ssr (getDocs does) HOT 2
- Profile CRUD
- [BUG] optimization: true cause Service functions is not available Error: Service functions is not available
- @ngx-env/builder:application is not a recognized builder HOT 4
- Deployment to Google Cloud Run using Angular v17 Application Builder not working
- [error] AssertionError [ERR_ASSERTION]: catch clause variable is not an Error instance HOT 2
- Appcheck on Angular 17 does not work! HOT 3
- How to tell FCM to load the firebase-messaging-sw file in a different call route(href)? in @angular/fire (FCM) HOT 1
- where is firestore.fieldValue? HOT 1
- After updating angular cli and angular core to 15, I'm getting error in firebase as no firebase app default has been created HOT 1
- serverTimestamp fails when uploading to firestore. HOT 2
- Can't set custom lang to email templates HOT 2
- Unhandled Promise rejection Analytics with SSR HOT 1
- [Android] Firestore snapshot listeners is slow to retrieve data.
- Compat sample does not compile
- Either AngularFireModule has not been provided in your AppModule HOT 1
- [Angular 15 + Firebase 7] Build in production mode error: Component auth has not been registered yet HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angularfire.