Martin Forsstedt Martin Forsstedt - 10 months ago 111
AngularJS Question

Can't get Firebase update() to work with provided object

Ok, so after a lot of trial and error I have to try asking here.
I'm trying to update a Firebase entry and my code look like this,

This is from my service.js:

//This dosn't work
var updateItem = function (item, id) {
var ref = new Firebase(FIREBASE_URI + '/lessons/' + id);

//This works (items is a ref to new Firebase(FIREBASE_URI + '/lessons/');
var addItem = function (item) {

And this is from my controller:

$scope.updateLesson = function (item) {
LessonsService.updateLesson(item, id);

The error I'm getting is this:

Error: Firebase.set failed: First argument contains an invalid key ($id). Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"

The object I'm passing in looks like this:

Object {
$id: "-JLIUvVMLqoCVgHaed9f",
$bind: function, $add: function, $save: function, $set: function…}
$add: function (item) {
$auth: function (token) {
$bind: function (scope, name, defaultFn) {
$child: function (key) {
$getIndex: function () {
$getRef: function () {
$id: "-JLIUvVMLqoCVgHaed9f"
$off: function (type, callback) {
$on: function (type, callback) {
$remove: function (key) {
$save: function (key) {
$set: function (newValue) {
$transaction: function (updateFn, applyLocally) {
$update: function (newValue) {
createDate: "2014-04-24T11:29:42.692Z"
desc: "test"
somemorevalues: "here"

I have tried to do a JSON.stringify on the object and got a nice looking result looking like this:

createDate: "2014-04-24T11:29:42.692Z",
desc: "test",
somemorevalues: "here"

But it wont accept it when I'm passing that in thru a variable. (Error: Firebase.update failed: First argument must be an object containing the children to replace.) If I pass it in directly as a string it works thou (?!!!). It's the exact same information in the variable.. What the hell am I missing?! As of now I'm building my own object like this:

var newItem = {
title: item.title,
desc: item.desc,
ingress: item.ingress,
workarea: item.workarea,
years: {val: item.years.val},

and passing that along to firebase, which works but is not ideal because its "static".

Answer Source

Use angularFire according to the API. Read the Angular+Firebase Overview for a good primer.

In essence, instead of passing angularFire objects into a Firebase ref (which will not work since keys may not have a $ in the name) and calling update/set yourself, simply use the $set/$update methods already available on the $firebase object:

var ref = $firebase(URL);
ref[id].desc = 'foo';