13

I am trying to three-way bind an input element to firebase database in Angular.js 2 (2.0.0-rc.4), using AngularFire 2 (2.0.0-beta.2).

I have a very simple html like:

<form (ngSubmit)="onSubmit()" #commentForm="ngForm">
  <input [(ngModel)]="model.author" type="input" name="author" required>
</form>

In my component, to save and retrieve contents of this input to firebase, I have an implementation like this:

export class CommentFormComponent implements OnInit, AfterViewInit {
  @ViewChild("commentForm") form;
  // http://stackoverflow.com/questions/34615425/how-to-watch-for-form-changes-in-angular-2

  firebaseInitComplete = false;
  model: Comment = new Comment("", "");
  firebaseForm: FirebaseObjectObservable<Comment>;

  constructor(private af: AngularFire) { }

  ngAfterViewInit() {
    this.form.control.valueChanges
      .subscribe(values => {
        // If we haven't get the initial value from firebase yet,
        // values will be empty strings. And we don't want to overwrite
        // real firebase value with empty string on page load
        if (!this.firebaseInitComplete) { return; }

        // If this is a change after page load (getting initial firebase value) update it on firebase to enable 3-way binding
        this.firebaseForm.update(values);
      });
  }

  ngOnInit() {
    this.firebaseForm = this.af.database.object("/currentComment");
    // Listen to changes on server
    this.firebaseForm.subscribe(data => {
      this.firebaseInitComplete = true; // Mark first data retrieved from server
      this.model = data;
    });
  }    
}

The code above works, I am able to read initial firebase value and update value on firebase when user type something in real time.

But having a manual logic to check for this.firebaseInitComplete and adding ngAfterViewInit to listen for changes feels a little bit wrong and I am just hacking it to work.

Is there a better implementation of three-way binding with less logic inside component?

3
  • 1
    Asking myself the same question. There do not appear to be any examples in the existing Firebase documentation outlining this very common use case. :( Commented Jan 2, 2017 at 20:11
  • 2
    When I read "three way binding" i almost had a stroke :/ Commented Feb 2, 2017 at 17:26
  • 1
    this makes me a sad panda Commented Feb 22, 2017 at 21:58

1 Answer 1

9

Seven months later and I have an answer for you.. extended ngModel syntax..

<input [ngModel]='(model|async)?.author' (ngModelChange)="model.update({author: $event})">

The [] block is a getter and the () block is a setter. Since the model's getter is actually unwrapping the FirebaseObjectObservable, you have to use the FirebaseObjectObservable's binding to set it.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks thats why I needed, but where did you find this? googled for hours, so little documentation/examples to be found for ionic/firebase combo
You saved my day! It's a bit different for me: [ngModel]="(product|async)?.quantity" (ngModelChange)="productRef.update({quantity: $event})" where: productRef = this.db.object() product = productRef.valueChanges() @angular/fire version 5.4.2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.