0

When you have an array of objects, how do you go about binding the changes of an object to firebase?

data looks like this:

[{ title: "Do Something", Due: "1425121200000", assignedTo: "Bill", description: "Do something", $id: wqejkkjebiewdf},
 { title: "Do Something else", Due: "1425121200000",  assignedTo: "Jim", description: "Do something else", $id: owenuwefwfliu}]

js:

var todos = this;
todos.tasks = [];
var todoRef = new Firebase(FB + "/tasks/" + CurrentFarm);
var todoArray = $firebase(todoRef).$asArray();
todoArray.$loaded(todos.tasks = todoArray);

html to show todos:

<div ng-repeat="task in todo.tasks | orderBy:'when'| filter: {done: true}">
<input type="checkbox" ng-model="task.done" ng-change="todo.taskDone(task)">
<span ng-repeat="users in task.users">{{getName(users)}} </span> 
<span> {{task.title}} </span>
<span> {{task.when | date:"EEEE, d MMMM, y"}} </span>
<input ng-click="editTask()" type="button"  value="Edit">
</div>

html for editing a todo. Note that I removed certain inputs from this code like date pickers etc to make it more readable.

<div  ng-show="editTaskMenu">
    <form  novalidate>
        <input ng-model="task.title" type="text" value="{{task.title}}">
        <textarea ng-model="task.description" value="{{task.description}}"></textarea>
        <input type="submit" value="Done" ng-click="finishedEditing()">
    </form>
</div>

The changes bind to the array in angular but do not get updated in firebase. From what I can tell there is no way to do three way binding with an array, so what is the work around here?

4
  • 1
    Please also show the relevant code of your solution, so we know how you've already tried to solve this problem. See stackoverflow.com/help/mcve Commented Mar 2, 2015 at 3:35
  • 1
    There is no need for a workaround. 3-way data bindings are simply a convenience. Call $save on the items when they are changed and they will be synchronized back to Firebase. Starting with a read-through of the guide will save you a great deal of thrashing on fundamentals like this. Commented Mar 2, 2015 at 17:50
  • @FrankvanPuffelen I added more code for you, hope it helps. I haven't got an attempted solution there but all I could think of was Kato's solution or similar which is to $save each input on the object individually on change. But I wanted to know the best way to do it since I thought it would be a commonly used thing. Commented Mar 2, 2015 at 19:45
  • 1
    I have an application where I use $asArray to show a list of items (so ng-repeat over them) and then allow editing of the selected object's properties through three-way binding (with $asObject and $bindTo). As usual: the bet way is the one that works for you use-case(s). Commented Mar 3, 2015 at 4:59

1 Answer 1

1

AngularFire accomplishes three-way binding, which is what you're looking for.

Take a look at the quick-start guide.


From the quick-start guide:

To sync data as an object:

var app = angular.module("sampleApp", ["firebase"]);
app.controller("SampleCtrl", function($scope, $firebaseObject) {
  var ref = new Firebase("https://<your-firebase>.firebaseio.com/data");
  // synchronize the object with a three-way data binding
  var syncObject = $firebaseObject(ref);
  syncObject.$bindTo($scope, "data");
});

Source: https://www.firebase.com/docs/web/libraries/angular/quickstart.html#section-objects

When you do that, syncObject will be bound to $scope.data, and any changes to $scope.data will update syncObject, and hence the data at the firebase location.

But what you want is $firebaseArray like so:

var app = angular.module("sampleApp", ["firebase"]);
app.controller("SampleCtrl", function($scope, $firebaseArray) {
  var ref = new Firebase("https://<your-firebase>.firebaseio.com/messages");
  // create a synchronized array for use in our HTML code
  $scope.messages = $firebaseArray(ref);
});

Source: https://www.firebase.com/docs/web/libraries/angular/quickstart.html#section-arrays


Here is the full AngularFire API documentation

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

6 Comments

Yes I have synced it .$asArray() And when an object is added to the array it syncs it to firebase which is great. But what I am asking is how do you sync the changes of an object within that array to firebase? ie updating a value of an object within that array rather than adding a new item to the array iteself.
You'd do that by also binding that specific object using $asObject as Sinan shows. Don't worry about the data transfer, Firebase is intelligent enough to transfer the data only once even when the same node is bound both with $asArray and $asObject.
Alternately, rather than setting up $asObject, you can just use $save() on the array, for the specific items with changes.
@FrankvanPuffelen Do you mean bind the same ref as the .$asArray using $asObject or do you mean bind each of the array items as objects?
@Kato Is there a way to detect changes in the object itself or would it be best to use ng-change on each of the inputs? There is about 6 inputs for each object so I was just concerned it wouldn't be very maintainable code.
|

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.