Firebase/AngularFire - When changing data locally, it gets synced across the app (bit hard to explain)

I have a weird issue with Firebase and I can’t find the answer anywhere.

Situation:
I have a list of firebase objects and a button to edit them.
When clicking on the edit-button, a modal appears with my data inside (the firebaseobject gets passed via NavParams).
If I make a change to this data, it gets synced to the list instantly, even if I don’t save the changes.

Is this default behaviour or do I have to add something to disable the “local binding”?

1
2
3
4

Impossible to comment specifically without seeing code.

General comment: If you are putting your Firebase call in your template, you’re doing it wrong stylistically. Place your calls to Firebase in providers. listOfObjectsStream() defined by AngularFIre2 goes in the provider. Then your page either directly reads this.providerName.listOfObjectsStream(), or (even better) interacts with a locally cached copy of that stream.

When you want to update someObject, you call a method in your provider, and the provider performs the update. Your page does not have direct interaction with Firebase. Otherwise, a buggy loop in your page could erase your entire data list. Encapsulate your database, as you would any local data structure.

Encapsulating the calls in a provider is the way to go, but doing that doesn’t change much (I think).

This is the flow of my data:

// Getting data
this.afDB.list('/koersdagen', 
{
  query: {
      orderByChild: 'datum'
    }
  }).map((array) => array.reverse())
  .take(1)
  .subscribe((data) =>
  {
    data.forEach(koersdag => 
    {
      this.koersdagen.push({ koersdag: koersdag, open: false });
    });
  })
// Open modal to edit data (data passed is an entry from firebase (in this.koersdagen[index].koersdag
editKoersdag(koersdag)
{
    let modal = this.modalCtrl.create(KoersdagModalPage, { koersdag: koersdag });
    modal.present();
}
// In the modal
this.koersdag = this.navParams.get("koersdag");
// HTML of modal
<ion-item>
  <ion-label>Datum</ion-label>
  <ion-datetime displayFormat="DD MMM YYYY" [(ngModel)]="koersdag.datum"></ion-datetime>
</ion-item>

When I change the date (or anything else), the value also changes in the list.
This happens without me updating the data to Firebase

How are you declaring koersdagen?

koersdagen: any = [];

koersdagen will change immediately, because of ngModel and the fact that navParams passes by reference. Are you saying you can also see the change in your Firebase console in real time?

No, console doesn’t change.

I need some kind of way to seperate the koersdagObject in the list and the one in the modal.

Would doing a this.afDB.object(“key”) from the modal solve this issue?
Or can I use navParams without passing a reference, but a copy?

You’re running into one of the biggest issues with Javascript. Almost nothing is immutable. Even “constants” are not constant. In the long term, what I think you should do is to learn Javascript ES6, which added several tools (like Object.assign and spread notation) to make deep copies. Personally, I use the library immutable.js and ES6 to make literally every variable immutable. I take a time and memory hit on purpose, because I consider it worth it. Whether you become that extreme is up to you.

Anyway, yes, make a deep copy. It’s much easier to avoid errors like this if you strongly type all variables and data structures. So in the long run, I think you need to get good at TypeScript and ES6, or you’ll run into this type of error again.

See here for a related discussion…

1 Like

Thank you both @pwespi and @AaronSterling!

I see where things went wrong but I thought it was Firebase showing of their realtime-syncing (even with local data)