2

I'm new to Backbone and Firebase. I'm using Backfire, have a collection:

var UsersCollection = Backbone.Firebase.Collection.extend({
    model: UserModel,
    firebase: new Firebase( "https://xxxxxx.firebaseio.com/users" ),
});

The model itself is not tied to Firebase (was getting "Invalid Firebase reference created" error):

var UserModel = Backbone.Model.extend({
    defaults: function() {
        return {
            email: "example@example.com"
        };
    }
});

In my View, I instantiate the collection, and I get the data okay, and I can add new models to the collection, as follows:

this.allUsers  = new UsersCollection();
...
this.allUsers.add( userData );

Works great, new user records appear on Firebase. However, let's say I now want to grab a given user's model and update its data:

var userRecord = this.allUsers.findWhere( {email: email} );
userRecord.set( {age: age} );

This updates the model locally but the changed model is NOT getting synced to Firebase. I tried userRecord.save(); afterwards but it triggers a "circular reference" error. Per the docs, set() should do it bur clearly something is off :(

David East
  • 31,526
  • 6
  • 67
  • 82
pete
  • 2,739
  • 4
  • 32
  • 46
  • So the real question is why does .save() return a circular reference error, since clearly calling set() does not persist the changes to Firebase. – Kato Nov 20 '14 at 18:59
  • Calling .set() does persist the changes to Firebase in the 0.4 version. I ran the same code and I was able to persist to Firebase. What are you using as your userData variable? – David East Nov 20 '14 at 21:50
  • The UserData is fairly simple, has one nested level: `{ "id": "-JDFx3e..", "email": "aaa@ex.com", "name": "Pete", "events": { "-Jxfe..": { "qty": 2 }, "-JzDa..": { "qty": 1 } } }` The add() to collection works fine. But when I try to set() on the extracted model, e.g. userRecord.set( { events: events } ), that operation works on the model locally but does not "persist" to Firebase for me. Is a standard Backbone model okay here, or do I need `Backbone.Firebase.Model.extend()` -- a bit unsure when to use it. – pete Nov 21 '14 at 00:35
  • Can you put this in a JSFiddle or JSBin? I was able to persist using `.set()` on the extracted model in my example. – David East Nov 21 '14 at 01:00
  • I'm not sure how to set up a Backbone/Firebase with all the dependencies on JSFiddle but it looks like the trouble is when updating the nested object values, e.g. `events`. Updating root-level values do persist to Firebase. For now, I can get around it by JSON.stringify'ing the nested objects under the `events` attribute. Or is perhaps how it's supposed to be handled? – pete Nov 21 '14 at 05:44
  • I put a sample of my [working demo here](http://jsbin.com/lexale/1/edit). Let me know where this varies from your implementation. You can create your own copy for any edits and send that to me as well. – David East Nov 21 '14 at 16:14

1 Answers1

3

The userRecord variable comes back as undefined in this case because the allUsers collection hasn't been populated with data yet. The data is still being downloaded to Firebase when you are calling .findWhere().

To avoid this, you can listen to the sync event and do all of your actions from there.

JSBin example.

allUsers.on('sync', function(collection) {
  // collection is allUsers
  var userRecord = collection.findWhere( {email: 'david@email.com'} );
  userRecord.on('change', function(model) {
     console.log('changed', model);
  });
  userRecord.set( {age:4} );
});

You'll want to ensure your collections are populated before you process any actions on them. The sync event is the recommended way to do this.

David East
  • 31,526
  • 6
  • 67
  • 82
  • Thanks for the `sync` tip. However, it definitely had a valid `userRecord` model when running `set()` on it. I've updated your [JSBin](http://jsbin.com/livuwe/2/edit) to try replicate; specifically I'm trying to update the `events` attribute of the model with a nested object. It seems to be persisting here, although the inner keys are coming back undefined? – pete Nov 22 '14 at 05:39
  • It's the same issue as before. When you update the userRecord it is an asynchronous action. You have to listen to the `change` method to ensure the data has returned. I've updated the answer and fiddle. – David East Nov 22 '14 at 19:18
  • Performing a set on the nested data in my app is a different issue for me (yet to return to it, probably having to do with the structure at this point) but this answer proved very useful elsewhere -- thanks! – pete Dec 01 '14 at 13:46
  • Shoot me an email if you're still having issues with this. – David East Dec 02 '14 at 12:23