<p dir="auto"><strong>I'm submitting a ...</strong>  (check one with "x")</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[x] feature request"><pre class="notranslate"><code class="notranslate">[x] feature request
</code></pre></div>
<p dir="auto"><strong>Current behavior</strong><br>
There's no way to list the current validators that are applied to a FormControl / AbstractControl.</p>
<p dir="auto"><strong>What is the motivation / use case for changing the behavior?</strong><br>
I'd like to create dynamic error messages, and apply attributes in child components based on the validators that are present.</p>
<p dir="auto">For example, I would like to be able to add the <code class="notranslate">maxlength</code> HTML attribute on to a text box control, if the maxLength validator is present (to reduce duplication) - but I need to be able to access the validator's metadata to do so.</p>
<p dir="auto">The closest I can get is the following, but because the <code class="notranslate">error</code> object only exists after the user has typed over the validator limit, I can only limit it to 11 chars, instead of the expected 10:</p>
<p dir="auto">FormBuilder config excerpt:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="firstName: ['', [Validators.required, Validators.maxLength(10)]]"><pre class="notranslate"><code class="notranslate">firstName: ['', [Validators.required, Validators.maxLength(10)]]
</code></pre></div>
<p dir="auto">Template:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;input type=&quot;text&quot;
    formControlName=&quot;firstName&quot;
    [attr.maxlength]=&quot;control.getError('maxlength')?.requiredLength&quot;"><pre class="notranslate"><code class="notranslate">&lt;input type="text"
    formControlName="firstName"
    [attr.maxlength]="control.getError('maxlength')?.requiredLength"
</code></pre></div>
<p dir="auto">Where <code class="notranslate">control</code> is an AbstractControl.</p>
<p dir="auto"><strong>Potential Bug</strong>:<br>
The string <code class="notranslate">"1"</code> results in query param value <code class="notranslate">true</code>:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="this.router.navigate([
    '/UserList',
    {page: '1'}
]);

// --&gt; /users/?page      (actual)
// --&gt; /users/?page=1  (expected)"><pre class="notranslate"><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">router</span><span class="pl-kos">.</span><span class="pl-en">navigate</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
    <span class="pl-s">'/UserList'</span><span class="pl-kos">,</span>
    <span class="pl-kos">{</span><span class="pl-c1">page</span>: <span class="pl-s">'1'</span><span class="pl-kos">}</span>
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// --&gt; /users/?page      (actual)</span>
<span class="pl-c">// --&gt; /users/?page=1  (expected)</span></pre></div>
<p dir="auto"><strong>Question</strong>:<br>
<em>Update: Duplicate of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="94040246" data-permission-text="Title is private" data-url="https://github.com/angular/angular/issues/2959" data-hovercard-type="issue" data-hovercard-url="/angular/angular/issues/2959/hovercard" href="https://github.com/angular/angular/issues/2959">#2959</a></em>.<br>
Is it intended that more complex query params aren't supported? Example:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="this.router.navigate([
    '/UserList',
    {
        filtering: {
            name: 'Andrew',
            age: 22
        }
    }
]);

// --&gt; /users/?filtering=[object%20Object]                 (actual)
// --&gt; /users/?filtering[name]=Andrew&amp;filtering[age]=22  (expected)"><pre class="notranslate"><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">router</span><span class="pl-kos">.</span><span class="pl-en">navigate</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
    <span class="pl-s">'/UserList'</span><span class="pl-kos">,</span>
    <span class="pl-kos">{</span>
        <span class="pl-c1">filtering</span>: <span class="pl-kos">{</span>
            <span class="pl-c1">name</span>: <span class="pl-s">'Andrew'</span><span class="pl-kos">,</span>
            <span class="pl-c1">age</span>: <span class="pl-c1">22</span>
        <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// --&gt; /users/?filtering=[object%20Object]                 (actual)</span>
<span class="pl-c">// --&gt; /users/?filtering[name]=Andrew&amp;filtering[age]=22  (expected)</span></pre></div>