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

Commit 6f3666b

Browse files
committed
Fix handling of primitive values, fixes #174
1 parent 7694be6 commit 6f3666b

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

angularfire.js

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ angular.module("firebase").filter("orderByPriority", function() {
7373
AngularFire = function($q, $parse, $timeout, ref) {
7474
this._q = $q;
7575
this._bound = false;
76+
this._loaded = false;
7677
this._parse = $parse;
7778
this._timeout = $timeout;
7879

@@ -211,6 +212,27 @@ AngularFire.prototype = {
211212
var self = this;
212213
var gotInitialValue = function(snapshot) {
213214
var value = snapshot.val();
215+
if (value === null) {
216+
// NULLs are handled specially. If there's a 3-way data binding
217+
// on a local primitive, then update that, otherwise switch to object
218+
// binding using child events.
219+
if (self._bound) {
220+
var local = self._parseObject(self._parse(self._name)(self._scope));
221+
switch (typeof local) {
222+
// Primitive defaults.
223+
case "string":
224+
case "undefined":
225+
value = "";
226+
break;
227+
case "number":
228+
value = 0;
229+
break;
230+
case "boolean":
231+
value = false;
232+
break;
233+
}
234+
}
235+
}
214236

215237
switch (typeof value) {
216238
// For primitive values, simply update the object returned.
@@ -229,6 +251,7 @@ AngularFire.prototype = {
229251
}
230252

231253
// Call handlers for the "loaded" event.
254+
self._loaded = true;
232255
self._broadcastEvent("loaded", value);
233256
};
234257

@@ -314,15 +337,18 @@ AngularFire.prototype = {
314337
var self = this;
315338
self._timeout(function() {
316339
// Primitive values are represented as a special object {$value: value}.
317-
self._object.$value = value;
340+
// Only update if the remote value is different from the local value.
341+
if (!self._object.$value || !angular.equals(self._object.$value, value)) {
342+
self._object.$value = value;
343+
}
318344

319345
// Call change handlers.
320346
self._broadcastEvent("change");
321347

322348
// If there's an implicit binding, simply update the local scope model.
323349
if (self._bound) {
324-
var local = self._parse(self._name)(self._scope);
325-
if (!angular.equals(value, local)) {
350+
var local = self._parseObject(self._parse(self._name)(self._scope));
351+
if (!angular.equals(local, value)) {
326352
self._parse(self._name).assign(self._scope, value);
327353
}
328354
}
@@ -359,17 +385,15 @@ AngularFire.prototype = {
359385
var self = this;
360386
var deferred = self._q.defer();
361387

362-
// _updateModel will take care of updating the local model if _bound
363-
// is set to true.
388+
// _updateModel or _updatePrimitive will take care of updating the local
389+
// model if _bound is set to true.
364390
self._name = name;
365391
self._bound = true;
366392
self._scope = scope;
367393

368-
// If the model on $scope is not set yet, make it an object.
394+
// If the local model is an object, call an update to set local values.
369395
var local = self._parse(name)(scope);
370-
if (local === undefined) {
371-
self._parse(name).assign(scope, {});
372-
} else {
396+
if (local !== undefined && typeof local == "object") {
373397
self._fRef.update(self._parseObject(local));
374398
}
375399

@@ -378,10 +402,19 @@ AngularFire.prototype = {
378402
var unbind = scope.$watch(name, function() {
379403
// If the new local value matches the current remote value, we don't
380404
// trigger a remote update.
381-
local = self._parseObject(self._parse(name)(scope));
382-
if (angular.equals(local, self._object)) {
405+
var local = self._parseObject(self._parse(name)(scope));
406+
if (self._object.$value && angular.equals(local, self._object.$value)) {
407+
return;
408+
} else if (angular.equals(local, self._object)) {
383409
return;
384410
}
411+
412+
// If the local model is undefined or the remote data hasn't been
413+
// loaded yet, don't update.
414+
if (local === undefined || !self._loaded) {
415+
return;
416+
}
417+
385418
// Use update if limits are in effect, set if not.
386419
if (self._fRef.set) {
387420
self._fRef.set(local);
@@ -403,6 +436,7 @@ AngularFire.prototype = {
403436
return deferred.promise;
404437
},
405438

439+
406440
// Parse a local model, removing all properties beginning with "$" and
407441
// converting $priority to ".priority".
408442
_parseObject: function(obj) {

0 commit comments

Comments
 (0)