I recently switched from angularfire 0.6 to to 0.8.0. I am having problems to save an item of a list, that contains an array itself.
My Objects account look like this:
{
"-JQruasomekeys0nrXxH" : {
"created" : "2014-03-23T22:00:10.176Z",
"durations" : [ {
"$$hashKey": "00L", // this is generated by ng-repeat on arrays
"end" : "2014-07-15T22:00:00.000Z",
"start" : "2014-07-09T22:00:00.000Z"
} ],
"email" : "[email protected]",
}
}
The durations are an array of time periods with start and end, which are resembled by a ng-repeat of two input fields in HTML.
<tr ng-repeat="duration in account.durations">
<td>
<input ng-model="duration.start" datepicker>
</td>
<td>
<input ng-model="duration.end" datepicker>
</td>
</tr>
Before saving the account to firebase, I am doing angular.copy($scope.account) in the Controller, to get rid of the angular $$hash values. This worked in angularfire 0.6.0.
In angularfire 0.8.0, I am still getting the error:
Error: Firebase.set failed: First argument contains an invalid key ($$hashKey) in property 'durations.0'. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]
How is this meant to be solved by angularfire, when working with objects, that have arrays within themselves? Durations won't be the only array I will have within the account. So is there a more professional solution, or do i have to angular.copy every single array object before saving to firebase via angularfire?
Thanks in advance for any hint.
Update (11. Aug 14) After doing a bit more research, the Problem is not that using angular.copy() does not work any more. actually it does. But it is very unhandy to update/modify an existing dataset with the angularfire method $save() (https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebaseobject-save) Because I can't seem to find a proper way to $save() an item after doing angular.copy().
Update 2 (12 Aug 14) I found a workaround for the moment, but actually a workaround is what I wanted to avoid in the first place:
// loop for every duration, that should clean the object from "$$hashKey" attributes
angular.forEach($scope.account.durations, function (value, index) {
var cleanValue = {};
// checks, if the date is a JSON string already
if (typeof value.start === 'string') {
cleanValue.start = value.start;
} else {
cleanValue.start = value.start.toJSON();
}
// checks, if the date is a JSON string already
if (typeof value.end === 'string') {
cleanValue.end = value.end;
} else {
cleanValue.end = value.end.toJSON();
}
// overwrite the array object at index to get loose of $$hashKey
$scope.account.durations[index] = cleanValue;
});
I think that this workaround takes the advantages off the document based principle in Firebase, as I have to know the exact attributes of an object before storing it via AngularFire.
Update 3 (13. AUg 14) I added a jsfiddle to show the problem: jsfiddle.net/1fem6byt
If you add lines to the array, and then try and save the object to the firebase, the $$hashKey error (given above) appears in the console. There are ways to workaround this problem, but I am looking for an easier, or cleaner solution with angularfire, if possible. I might not do adding of lines correctly – or do I miss something?