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

Commit

Permalink
feat(formly-form): formlyField.runExpressions resolve after fields set
Browse files Browse the repository at this point in the history
* feat(formly-form): formlyField.runExpressions resolve after fields set

* test(formly-form): ensure expressions finish before validators run
  • Loading branch information
pseudo-su authored and Kent C. Dodds committed Jul 26, 2016
1 parent a4c54bb commit 2073a91
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 4 deletions.
15 changes: 11 additions & 4 deletions src/directives/formly-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,25 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo

// function definitions
function runExpressions() {
const deferred = $q.defer()
// must run on next tick to make sure that the current value is correct.
return $timeout(function runExpressionsOnNextTick() {
$timeout(function runExpressionsOnNextTick() {
const promises = []
const field = $scope.options
const currentValue = valueGetterSetter()
angular.forEach(field.expressionProperties, function runExpression(expression, prop) {
const setter = $parse(prop).assign
const promise = $q.when(formlyUtil.formlyEval($scope, expression, currentValue, currentValue))
promise.then(function setFieldValue(value) {
setter(field, value)
})
.then(function setFieldValue(value) {
setter(field, value)
})
promises.push(promise)
})
$q.all(promises).then(function() {
deferred.resolve()
})
}, 0, false)
return deferred.promise
}

function watchExpressions() {
Expand Down
43 changes: 43 additions & 0 deletions src/directives/formly-form.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1314,4 +1314,47 @@ describe('formly-form', () => {
})
})
})
describe('extras', () => {
describe('validateOnModelChange', () => {
it('should run validators after expressions are set', () => {
let inputs, invalidInputs, el

scope.model = {
foo: null,
bar: 123,
}

scope.fields = [
{template: input, key: 'foo', extras: {validateOnModelChange: true}},
{template: input, key: 'bar', templateOptions: {type: 'number'}},
]
// First Field isn't valid when second field is 1
scope.fields[0].expressionProperties = {
'templateOptions.isValid': 'model.bar !== 1',
}
// validator to use isValid attribute
scope.fields[0].validators = {isValid: {expression: (viewValue, modelValue, fieldScope) => {
return fieldScope.to.isValid
}}}

el = compileAndDigest()

// Input state before
inputs = el[0].querySelectorAll('input')
invalidInputs = el[0].querySelectorAll('input.ng-invalid')
expect(inputs.length).to.equal(2)
expect(invalidInputs.length).to.equal(0)

// Enter '1' into second field
angular.element(inputs[1]).val(1).triggerHandler('change')
$timeout.flush()

// Input state after
inputs = el[0].querySelectorAll('input')
invalidInputs = el[0].querySelectorAll('input.ng-invalid')
expect(inputs.length).to.equal(2)
expect(invalidInputs.length).to.equal(1)
})
})
})
})

0 comments on commit 2073a91

Please sign in to comment.