Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase/AngularFire2: Push data not directly, only after pressing the save-button

i've got a configuration-screen with an Ionic ion-list, where the user can add items to the list and also the current entries of the list are being shown. I want the user to be able to add new items via a button. the new items should not immediatelly be saved to firebase - the user has to press a save-button to do this. currently my code looks like this

  <ion-list *ngIf="regimeList">
    <ion-list-header color="secondary">Items
      <button class="my-select" ion-button outline item-end (click)="addItem()">+</button>
    </ion-list-header>
      <ion-item *ngFor="let item of itemList">
        {{item.name}}
      </ion-item>
  </ion-list>

the data for itemList is from a observable with a little mapping/formating:

this.$ref = this.database.list('/items/' + uid);
this.$ref.subscribe(snapshot => { this.map2itemList(snapshot) });

when the user clicks the ion-button, he gets a popup where he can enter a new item. on pressing "ok", the new entry should be show in the list, but not saved to firebase. So i cant use

this.$ref.push(myNewItem);

because of the observable the data will directly be commited and my view updated. what is a good strategy to seperate these two actions? thank you in advance.

like image 529
mario Avatar asked Nov 19 '22 11:11

mario


1 Answers

Here is a class that could help you. It's a bit ugly and not tested but it should work.

import { Observable } from 'rxjs';

class ObservableFirebaseListWithTempStorage {
    private observer;
    private tempItems: Array<any>;
    private dbItems: Array<any>;
    public items: Observable<Array<any>>;

    constructor(private $ref, private mapFunction) {
        this.items = Observable.create(observer => {
            this.observer = observer;
        });
        $ref.subscribe(snapshot => {
            this.dbItems = this.mapFunction(snapshot);
            this.updateItems();
        });
    }
    private updateItems(){
        let tempList = [];
        tempList.push(this.dbItems);
        tempList.push(this.tempItems);
        this.observer.next(tempList)
    }
    public addItem(item): void {
        this.tempItems.push(item);
        this.updateItems();
    }
    public saveItems():void{
        this.tempItems.forEach(item=>{
            this.$ref.push(item);      
        });
    };
}

You should change your map2itemList() a bit so it takes the snapshot as parameter and returns the mapped items, not setting something.

Now you can create a instance of that class:

let items = new ObservableFirebaseListWithTempStorage(this.$ref, this.map2itemList);
this.itemList = items.items;

Add a item with:

this.items.addItem(yourNewTempItem);

and save the items to the db:

this.items.saveItems();
like image 87
Jonas Wyss Avatar answered Dec 15 '22 15:12

Jonas Wyss