Reputation: 1
When extending $firebaseArray I get the error 'invalid key $id (cannot contain .$[]#)'
The issue is with the $id property on the book object. When calling $save on the array and passing the modified book in, the factory doesn't recognize $id as the id field like it normally would prior to extending.
Html
<ul>
<li ng-repeat="book in bookList"> <a href="#" ng-click="loadBook(book)">{{book.$id}}: {{book.date|date:"medium"}}</a>
<button ng-click="setDate(book)">set date</button>
</li>
</ul>
<pre>{{book|json}}</pre>
Javascript
// reference to our Firebase instance
var fb = new Firebase('YourUrl');
function Book(snap) {
// records in synchronized arrays must have a $id property
this.$id = snap.key();
this.update(snap);
}
Book.prototype.update = function (snap) {
angular.extend(this, snap.val());
// convert json dates to Date objects
this.date = new Date(this.date||0);
this.$priority = snap.getPriority();
};
Book.prototype.toJSON = function() {
return angular.extend({}, this, {
// revert Date objects to json data
date: this.date.getTime()
});
};
var app = angular.module('app', ['firebase']);
app.controller('ctrl', function ($scope, bookFactory) {
// create a synchronized array with a customized version
// of $FirebaseArray
$scope.bookList = new bookFactory(fb);
// loads a single record for display
$scope.book = "Click on a book id";
$scope.loadBook = function (book) {
$scope.book = book;
};
// changes the date on a book record, note that we're working
// with Date objects here
$scope.setDate = function(book) {
book.date = new Date();
$scope.bookList.$save(book);
};
});
app.factory('bookFactory', function ($firebaseArray, $firebaseUtils) {
return $firebaseArray.$extend({
// override $$added to return a Book object
$$added: function (snap, prevChild) {
return new Book(snap);
},
// override $$updated to update the book object
$$updated: function (snap) {
var rec = this.$getRecord(snap.name());
if(angular.isObject(rec) ) {
book.update(snap);
}
}
});
});
Made a fiddle showing the error, just press 'Set Date' on any of the books. https://jsfiddle.net/jensenben/h98mjsoz/
This can be remedied if make the book object use id instead of $id and add a $$getKey method to the $extend call to tell it what field has the id in it, but I'd prefer to stick with the traditional $id field that I use when not extending a $firebaseArray.
function Book(snap) {
// records in synchronized arrays must have a $id property
this.id = snap.key();
this.update(snap);
}
return $firebaseArray.$extend({
$$getKey: function(rec) {
return rec.id;
},
...
Upvotes: 0
Views: 480
Reputation: 599061
There's a bit much going on, so I'm not sure if this is your problem. But to get rid of the error, convert the $firebaseObject()
to a regular JSON object when saving:
$scope.setDate = function(book) {
book.date = new Date();
$scope.bookList.$save(book.toJSON());
};
Note that the CSS and most of the JavaScript code are irrelevant to the problem.
Upvotes: 1