title: How do I perform a 3-way binding with UI-Grid and Firebase?
body: <p>I have an Angular UI grid filled with data that I pulled from Firebase. The grid table views perfectly with the $.asArray method with AngularFire, with the relevant code snippets as follows.</p>
  
  <p><strong>The Html View:</strong></p>
  
  <pre><code>&lt;!-- UI-Grid --&gt;
  &lt;div ui-grid="gridOptions" class="ui-grid" ui-grid-resize-columns ui-grid-edit&gt;&lt;/div&gt;
  </code></pre>
  
  <p><strong>The Controller View:</strong></p>
  
  <pre><code>var ref = new Firebase("https://commentme.firebaseio.com/comments");    
  
  // create an AngularFire reference to the data
  var sync = $firebase(ref);
  
  // create a synchronized array for use in our HTML code
  $scope.comments = sync.$asArray();
  
  $scope.newComment = {text: '', date: ''};
  
  // pushes data back to Firebase Array
  $scope.addComment = function(){
    $scope.comments.$add($scope.newComment);           
    $scope.newComment = {text: '', date: ''};
  
  // UI Grid Options  
  $scope.gridOptions = {
    enableSorting: true,
    columnDefs: [
    { name: 'comments', field: 'text'},
    { name: 'date', field: 'date'}
  
    ],
    data: $scope.comments 
  };
  </code></pre>
  
  <p>The problem however is when I make edits to the UI-Grid (using the ui.grid.edit module) those changes only can reflect on my DOM and cannot persist/3-way bind back to the Firebase backend.</p>
  
  <p>I tried binding the ng-model and ng-change using the <em>editableCellTemplate</em> within <em>ColumnDefs</em> with a code like this but still could not get it working.</p>
  
  <pre><code>editableCellTemplate: '&lt;input type="text" ng-model="text" ng-change="comments.$save(text)"&gt;
  </code></pre>
  
  <p>Would appreciate if anyone could show me how to perform a 3-way bind with Firebase if I make changes to the cells of the UI-Grid table, thanks!</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Thanks to Kato's suggestions, I have finally made the binding between UI-Grid and Firebase! The solution is as follows.</p>
  
  <p><strong>The Html View:</strong></p>
  
  <pre><code>&lt;!-- UI-Grid --&gt;
  &lt;div ui-grid="gridOptions" class="ui-grid" ui-grid-resize-columns ui-grid-edit ui-grid-row-edit ui-grid-cellNav&gt;&lt;/div&gt;
  </code></pre>
  
  <p><strong>The Controller View:</strong></p>
  
  <pre><code>$scope.gridOptions.onRegisterApi = function(gridApi){
  
    //set gridApi on scope
    $scope.gridApi = gridApi;                  
    gridApi.rowEdit.on.saveRow($scope, $scope.saveRow);
  };
  
  $scope.saveRow = function( rowEntity ) { 
  
    //Firebase save and promise return
    $scope.comments.$save(rowEntity).then(function(ref){
      ref = $scope.comments;   
    }); 
  
    // create a fake promise - normally you'd use the promise returned by $http or $resource
    var promise = $q.defer();
    $scope.gridApi.rowEdit.setSavePromise( $scope.gridApi.grid, rowEntity, promise.promise );
  
    // fake a delay of 1 seconds whilst the save occurs, return error if item is empty
    $interval( function() {
      if (rowEntity === '' ){
        promise.reject();
      } else {
          promise.resolve();
        }
      }, 1000, 1);      
  
  };
  </code></pre>
  
  <p>I have used a fake promise as I am not sure how to bind the returned promise from Firebase to the setSavePromise method. A promise is needed as UI-Grid will not allow you to re-edit the cells without the promise returned.</p>