Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

saving new property overwrites firebase object

I am working on a quiz using firebase and angular. At the end of the quiz i want to save a new property to the users object using this code:

function saveTopscore() {
    var ref = new Firebase(CONSTANTS.FIREBASE_URL + 'users/' + User.user.$id + '/');
    var userObject = $firebaseObject(ref);
    userObject.topscore = User.totalCorrect;
    userObject.$save().then(function(ref) {
        console.log("worked");
    }, function(error) {
        console.log(error);
    });
}

And it works, but it also overwrite all the properties of the user object. So the object used to hold like a name, username, email, password etc, but when i push the topscore it becomes the only property of the object. Why?

like image 756
idontknow Avatar asked Nov 30 '25 12:11

idontknow


2 Answers

Why are you using $firebaseObject here? That is only useful if you three-way bind it to an Angular view. If you're in regular JavaScript code, just stick to Firebase's regular JavaScript SDK.

In this case, just do:

ref.update({ topscore: User.totalCorrect });
like image 106
Frank van Puffelen Avatar answered Dec 02 '25 04:12

Frank van Puffelen


As @Frank said, use the JavaScript SDK.

I wanted to clarify the original context (using $firebaseObject) in case anyone else refers to this question in the future.

  • The original symptom is happening because you're setting a single parameter of the object and saving it before the object (and its already-existing children) have been fully downloaded.
  • So, at the time when you call .$save(), userObject will (most likely) only have its topscore parameter set, and calling .$save() will effectively remove all of the other pre-existing children at the Firebase ref.

You could avoid this using .$loaded() to wait until the object has fully downloaded before modifying and/or updating it...

EDIT: However, as the Intro to AngularFire guide states,

The $loaded() method should be used with care as it's only called once after initial load. Using it for anything but debugging is usually a poor practice.

If you were to ignore this warning and use $loaded() anyway, that implementation could look like this:

Note - ANTIPATTERN: This is not a recommended practice.

var ref = new Firebase(fbUrl + '/users/' + User.user.$id + '/');
var userObject = $firebaseObject(ref);
// wait until userObject has been downloaded, then modify & save it.
userObject.$loaded().then(function(){
  userObject.topscore = User.totalCorrect;
  userObject.$save().then(function(ref) {
      console.log("Saved");
  }, function(error) {
      console.log(error);
  });
});

As Frank said in the comments to this answer,

"If you're using $loaded() straight after $firebaseObject (or $firebaseArray), you're probably doing something wrong."

like image 25
sbolel Avatar answered Dec 02 '25 04:12

sbolel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!