Code Monkey home page Code Monkey logo

Comments (7)

davideast avatar davideast commented on May 22, 2024

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.

jeffbcross avatar jeffbcross commented on May 22, 2024

Hello? Update plz?

from angularfire.

davideast avatar davideast commented on May 22, 2024

Okay, after further thought and review, here is my proposal:

JSBin Demo

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.

jeffbcross avatar jeffbcross commented on May 22, 2024

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.

katowulf avatar katowulf commented on May 22, 2024

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.

jeffbcross avatar jeffbcross commented on May 22, 2024

@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.

davideast avatar davideast commented on May 22, 2024

@jeffbcross I'm working on this and #73 since they are related.

from angularfire.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.