Malformed JSON When Loading $scope.model.value In Custom Umbraco Data Type
I'm occasionally noticing strange behaviour in the data that Umbraco initializes my data types $scope.model.value
value with.
I'm working with Umbraco 7.11.1, and my custom data type is built around a complex JSON based data model.
During "Save and Publish" (from the Umbraco back-office), Umbraco seems to accept the JSON that my controller has stored in $scope.model.value
- no error dialogs are displayed, console errors logged, etc.
When the back-office reloads however, Umbraco attempts to initialize my data type with a partial, malformed JSON string, rather than the expected JSON object (ie that was previously saved).
I'm following the regular pattern for implementing a custom data type, via an angularjs controller:
angular.module('umbraco')
.controller('MyDataType', ['$scope', function ($scope) {
var loadedData = $scope.model.value;
// Do stuff with "loadedData"
$scope.model.value = loadedData;
}])
The issue seems to occur when I have a large amount of data in my JSON model (ie json that would serialize to ~150 characters or more)
Is there a limit to the amount of data that I can store in an Umbraco data type? Or is there something else that I am overlooking here?
Answer
The solution to this problem was to sanitize the JSON data that my controller stored in $scope.model.value
.
It seems that Umbraco is sensitive to the extra metadata "stuff" that angularjs drops into scope variables ("$$hashKey", etc) and this appears to be what caused my datatype to be subsequently initialized with a malformed JSON string rather than the expected JSON object.
In the end, I opted to:
- clone the model value (ie
$scope.myModel
as shown below) that my data type was initialized with - set up a
$watcher
to synchronize$model.scope.value
with any changes made to$scope.myModel
- during synchronization, store a sanitized clone of
$scope.myModel
(ie that excludes internal angular metadata like "$$hashKey") in$model.scope.value
Example pseudo code demonstrating solution:
angular.module('umbraco')
.controller('MyDataType', ['$scope', function ($scope) {
$scope.myModel = cloneValue($scope.model.value)
var endWatcher = $scope.$watch('myModel', function() {
$scope.model.value = cloneAndSanitizeMyModel($scope.myModel)
});
$scope.$on('$destroy', function() {
endWatcher();
});
}])
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM