Open da-mkay opened 5 years ago
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.
Find more details about Angular's feature request process in our documentation.
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
🚀 Feature request
Command (mark with an
x
)Description
I am currently writing a builder and the appropriate JSON schema to validate its options. The builder will be used in different targets, but all of these targets usually share some base options which is why I added some target reference support, similar to the
browserTarget
option of the@angular-devkit/build-angular:dev-server
builder. An example config could look like this:So, at the end the options of
target2
should be evaluated to the following:This should be as simple as using some Object.assign code:
But the problem is, that Angular modifies the incoming options-object. It passes in an empty object for the
b
property oftarget2
's options:{ "a": "bar", "b": {} }
. Thus,result.b
will be{}
instead of{ "asd": "wer" }
. This is done by the Angular's postTransformaddUndefinedDefaults
which is always added to theCoreSchemaRegistry
. In theory postTransforms can be disabled as seen here usingapplyPostTransforms: false
. However, it is not possible to override this value when the builder's schema is compiled and the validator is used, see here (no second argument is passed tovalidation
).Of course, I could add some code to my builder that checks for that
{}
and ignores it. But actually, it should be possible to explicitly setb: {}
to override the inherited value, e.g.:So I really need to distinguish between the
{}
set by the user and the{}
set by the postTransform.NOTE: All of this affects options that are set to type
object
orarray
(in which case[]
is used as default) in the schema.Describe the solution you'd like
It would be nice to be able to disable postTransforms for a specific builder, for example in the builder code itself.
Actually I do not know why the
addUndefinedDefaults
transform is used at all, but there is probably a reason for that. Is it? 😛Describe alternatives you've considered
I cannot imagine any workarounds. Angular modifies the options passed to a builder where it should not, IMHO. In the above case, the user does not specified a
b
property, but Angular passes in an empty object forb
. And currently there is no way to change that behavior, as far as I can see.EDIT: I did find a workaround, but it is an ugly hack as it relies on the internals of
addUndefinedDefault
and thus could easily break when Angular is updated.Instead of this schema:
One can use this schema:
This works, because Angular detects that two types are possible for
b
:object
andnull
. This causes Angular to not override the value. Of course,null
is now a valid value forb
, too, but that may not be a problem in some cases.