Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Add defaults to records in synchonized objects/arrays #372

Closed
katowulf opened this issue Aug 1, 2014 · 5 comments
Closed

Add defaults to records in synchonized objects/arrays #372

katowulf opened this issue Aug 1, 2014 · 5 comments

Comments

@katowulf
Copy link
Contributor

katowulf commented Aug 1, 2014

The methodology for creating/updating records deletes any keys on the client which don't exist on the server. The original plan of setting defaults inside $loaded is effective, but a bit awkward and verbose as it requires advanced knowledge of how to pass a constructor function to $extendFactory:

var DefaultsFactory = $FirebaseObject.$extendFactory(function() {
    $FirebaseObject.apply(this, arguments);
    var self = this;
    var defaults = { ... };
    self.$loaded(function() {
         angular.each(defaults, function(v, k) {
              if( !self.hasOwnProperty(k) ) { self[k] = v; }
         });
    });
}, {
   /* prototype methods go here */
});

It could also be done by the callee, but then we're back to hacking on the instance externally:

var defaults = { ... };
var obj = $firebase(ref).$asObject();
// could be wrapped in a service
// but still externally modifying the synchronized object
obj.$loaded(function() {
    angular.each(defaults, function(v, k) {
         if( !obj.hasOwnProperty(k) ) { obj[k] = v; }
    });
});

Additionally, they may be deleted again on the next server update if the fields do not exist remotely. This condition shouldn't happen, since the record should not get saved to the server with missing defaults (i.e. required fields) and security rules validation should probably catch this.

However, there are a few cases where it's nice to have a looser interpretation of remote data, such as when a missing remote value has special meaning (but creates a lot of if/else logic locally that we want to avoid). Additionally, if security rule prevents the initial create/set op from succeeding, the local values are inexplicably deleted (because the local value event is raised with null to reconcile the server data with local), which compounds the debugging effort.

Ideas for a solution: Investigate a simple way to apply local defaults. Something like a $$defaults property should be sufficient. It would be applied during $$added and $$updated to ensure keys in that list are set locally if not found remotely. This reduces the above syntax to this:

var DefaultsFactory = $FirebaseObject.$extendFactory({
   $$defaults: { ... }
   /* prototype methods go here, too */
});

Note that this does not resolve the case where users add fields onto their record which do not exist in the remote data. Those fields will be deleted during update. This is easily fixed by overriding $$updated not to delete the fields specified, but should also be pondered. I think this is a sufficient solution but maybe not an obvious one.

@joshbowdoin
Copy link
Contributor

Note that this does not resolve the case where users add fields onto their record which do not exist in the remote data.

I've solved this by prefixing local-only properties with '$', which I noticed is not deleted because of the way $firebaseUtils.each is written. One could alternatively use '_' or '.' similarly.

Is this not recommended? Do you envision changing the way $firebaseUtils.each works?

@katowulf
Copy link
Contributor Author

katowulf commented Aug 1, 2014

@joshbowdoin No, you've used it as intended. There are some caveats to using $ preifxes though--they don't fire $scope's $watch at all, they are not considered as part of angular.equals. I'm always pondering how to make things simpler and to abstract these complexities.

@joshbowdoin
Copy link
Contributor

Yeah, I submitted an issue with angularjs as far as angular.equals not considering '$' properties. I'm convinced that it is now a bug (produced by the changes to their API). Haven't gotten much response yet. :( (angular/angular.js#8325)

So, perhaps I should switch to using '_' then, huh?

@katowulf
Copy link
Contributor Author

katowulf commented Aug 1, 2014

We were thinking about prefixing everything with ☃. It's sort of awesome. But yes, _ would work for things you want to work with watch/equals.

@joshbowdoin
Copy link
Contributor

That'd be awesome! :)

Josh Bowdoin
Athletic.net Development

On Fri, Aug 1, 2014 at 2:27 PM, katowulf [email protected] wrote:

We were thinking about prefixing everything with ☃. It's sort of awesome.
But yes, _ would work for things you want to work with watch/equals.


Reply to this email directly or view it on GitHub
#372 (comment)
.

@jwngr jwngr added this to the 0.8.1 Release milestone Aug 7, 2014
@katowulf katowulf self-assigned this Aug 7, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants