Skip to content
This repository was archived by the owner on Apr 30, 2018. It is now read-only.

Commit 9a35781

Browse files
feat(formly-form): Use arrays for fieldTransforms
Documentation and deprecation warnings for both options and formConfig.extras Fixes #458
1 parent c45a474 commit 9a35781

File tree

4 files changed

+83
-9
lines changed

4 files changed

+83
-9
lines changed

other/ERRORS_AND_WARNINGS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ of the expression, the scope you're passed wont have all the properties you may
127127
See documentation [here](http://docs.angular-formly.com/docs/field-configuration-object#hideexpression-string--function)
128128
and an example [here](http://angular-formly.com/#/example/field-options/hide-fields)
129129

130+
# FieldTransform as a function deprecated
131+
132+
To allow for plugin like functionality, `fieldTransform` functions on `formlyConfig.extras` and `formly-form.options`
133+
are now deprecated. Moving forward fieldTransform will accept an array of `fieldTransform` functions. This makes it possible
134+
to have multiple fieldTransforms. Note, `fieldTransform` functions will be removed in a major release.
135+
130136
# Notes
131137

132138
It is recommended to disable warnings in production using `formlyConfigProvider.disableWarnings = true`. Note: This will

src/directives/formly-form.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,21 +133,47 @@ function formlyForm(formlyUsability, formlyWarn, $parse, formlyConfig, $interpol
133133

134134
function setupFields() {
135135
$scope.fields = $scope.fields || [];
136-
const fieldTransform = $scope.options.fieldTransform || formlyConfig.extras.fieldTransform;
137136

138-
if (fieldTransform) {
139-
$scope.fields = fieldTransform($scope.fields, $scope.model, $scope.options, $scope.form);
140-
if (!$scope.fields) {
141-
throw formlyUsability.getFormlyError('fieldTransform must return an array of fields');
142-
}
137+
checkDeprecatedOptions($scope.options);
138+
139+
let fieldTransforms = $scope.options.fieldTransform || formlyConfig.extras.fieldTransform;
140+
141+
if (!angular.isArray(fieldTransforms)) {
142+
fieldTransforms = [fieldTransforms];
143143
}
144144

145+
angular.forEach(fieldTransforms, function transformFields(fieldTransform) {
146+
if (fieldTransform) {
147+
$scope.fields = fieldTransform($scope.fields, $scope.model, $scope.options, $scope.form);
148+
if (!$scope.fields) {
149+
throw formlyUsability.getFormlyError('fieldTransform must return an array of fields');
150+
}
151+
}
152+
});
153+
145154
setupModels();
146155

147156
angular.forEach($scope.fields, attachKey); // attaches a key based on the index if a key isn't specified
148157
angular.forEach($scope.fields, setupWatchers); // setup watchers for all fields
149158
}
150159

160+
function checkDeprecatedOptions(options) {
161+
if (formlyConfig.extras.fieldTransform && angular.isFunction(formlyConfig.extras.fieldTransform)) {
162+
formlyWarn(
163+
'fieldtransform-as-a-function-deprecated',
164+
'fieldTransform as a function has been deprecated.',
165+
`Attempted for formlyConfig.extras: ${formlyConfig.extras.fieldTransform.name}`,
166+
formlyConfig.extras
167+
);
168+
} else if (options.fieldTransform && angular.isFunction(options.fieldTransform)) {
169+
formlyWarn(
170+
'fieldtransform-as-a-function-deprecated',
171+
'fieldTransform as a function has been deprecated.',
172+
`Attempted for form`,
173+
options
174+
);
175+
}
176+
}
151177

152178
function setupOptions() {
153179
formlyApiCheck.throw(

src/directives/formly-form.test.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import testUtils from '../test.utils.js';
66
import angular from 'angular-fix';
77
import _ from 'lodash';
88

9-
const {getNewField, input, basicForm} = testUtils;
9+
const {getNewField, input, basicForm, shouldWarnWithLog} = testUtils;
1010

1111
describe('formly-form', () => {
1212
let $compile, formlyConfig, scope, el, $timeout;
@@ -759,6 +759,33 @@ describe('formly-form', () => {
759759
formlyConfig.extras.fieldTransform = fieldTransform;
760760
});
761761

762+
it(`should give a deprecation warning when formlyConfig.extras.fieldTransform is a function rather than an array`, inject(($log) => {
763+
shouldWarnWithLog(
764+
$log,
765+
[
766+
'Formly Warning:',
767+
'fieldTransform as a function has been deprecated.',
768+
/Attempted for formlyConfig.extras/
769+
],
770+
compileAndDigest
771+
);
772+
}));
773+
774+
it(`should give a deprecation warning when options.fieldTransform function rather than an array`, inject(($log) => {
775+
formlyConfig.extras.fieldTransform = undefined;
776+
scope.fields = [getNewField()];
777+
scope.options.fieldTransform = fields => fields;
778+
shouldWarnWithLog(
779+
$log,
780+
[
781+
'Formly Warning:',
782+
'fieldTransform as a function has been deprecated.',
783+
'Attempted for form'
784+
],
785+
compileAndDigest
786+
);
787+
}));
788+
762789
it(`should throw an error if something is passed in and nothing is returned`, () => {
763790
scope.fields = [getNewField()];
764791
scope.options.fieldTransform = function() {
@@ -778,6 +805,20 @@ describe('formly-form', () => {
778805
doExpectations(spy);
779806
});
780807

808+
it(`should allow you to use an array of transform functions`, () => {
809+
scope.fields = [getNewField({
810+
customThing: 'foo',
811+
otherCustomThing: {
812+
whatever: '|-o-|'
813+
}})];
814+
scope.options.fieldTransform = [fieldTransform];
815+
expect(() => compileAndDigest()).to.not.throw();
816+
817+
const field = scope.fields[0];
818+
expect(field).to.have.deep.property('data.customThing');
819+
expect(field).to.have.deep.property('data.otherCustomThing');
820+
});
821+
781822
function doExpectations(spy) {
782823
const originalFields = [{
783824
key: 'keyProp',

src/providers/formlyApiCheck.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,16 @@ const fieldOptionsApiShape = {
158158

159159
const formlyFieldOptions = apiCheck.shape(fieldOptionsApiShape).strict;
160160

161-
162161
const formOptionsApi = apiCheck.shape({
163162
formState: apiCheck.object.optional,
164163
resetModel: apiCheck.func.optional,
165164
updateInitialValue: apiCheck.func.optional,
166165
removeChromeAutoComplete: apiCheck.bool.optional,
167166
templateManipulators: templateManipulators.optional,
168167
wrapper: specifyWrapperType.optional,
169-
fieldTransform: apiCheck.func.optional,
168+
fieldTransform: apiCheck.oneOfType([
169+
apiCheck.func, apiCheck.array
170+
]).optional,
170171
data: apiCheck.object.optional
171172
}).strict;
172173

0 commit comments

Comments
 (0)