Is there a way to use a FormArray as the top level form











up vote
1
down vote

favorite












I'm using @ngular/core 6.1.1 and @angular/forms 6.1.1



I'm trying to write a ControlValueAccessor which will manage an array of values.



I'm using reactive forms and declaring my form like this:



export class ItemsFormComponent implements ControlValueAccor, OnInit {

public form: FormArray;

public items: string = ['foo', 'bar', 'baz'];

constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.array(this.items.map((item) => new FormControl(item)));

this.form.valueChanges
.debounceTime(200)
.subscribe((items: string) => {
this.onChangeFn(items);
});
}
}


But then, I get a Template parsing error with



<ol [formArray]="form">
...
</ol>


Can't bind to 'formArray' since it isn't a known property of 'ol'



I DID include the FormsModule and the ReactiveFormsModule in my Feature Module. Any other form based on FormGroup work.



It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway.



So is there no way to use a FormArray as the top level form? Ideally, I'd like to avoid creating a FormGroup with a single FormArray in it.










share|improve this question






















  • "It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway." Why? For me is correct
    – Eliseo
    Nov 10 at 13:36










  • OK, it builds in prod with <ol [formGroup]="form"> but it still looks like a hack to me..
    – paztek
    Nov 10 at 13:49















up vote
1
down vote

favorite












I'm using @ngular/core 6.1.1 and @angular/forms 6.1.1



I'm trying to write a ControlValueAccessor which will manage an array of values.



I'm using reactive forms and declaring my form like this:



export class ItemsFormComponent implements ControlValueAccor, OnInit {

public form: FormArray;

public items: string = ['foo', 'bar', 'baz'];

constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.array(this.items.map((item) => new FormControl(item)));

this.form.valueChanges
.debounceTime(200)
.subscribe((items: string) => {
this.onChangeFn(items);
});
}
}


But then, I get a Template parsing error with



<ol [formArray]="form">
...
</ol>


Can't bind to 'formArray' since it isn't a known property of 'ol'



I DID include the FormsModule and the ReactiveFormsModule in my Feature Module. Any other form based on FormGroup work.



It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway.



So is there no way to use a FormArray as the top level form? Ideally, I'd like to avoid creating a FormGroup with a single FormArray in it.










share|improve this question






















  • "It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway." Why? For me is correct
    – Eliseo
    Nov 10 at 13:36










  • OK, it builds in prod with <ol [formGroup]="form"> but it still looks like a hack to me..
    – paztek
    Nov 10 at 13:49













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I'm using @ngular/core 6.1.1 and @angular/forms 6.1.1



I'm trying to write a ControlValueAccessor which will manage an array of values.



I'm using reactive forms and declaring my form like this:



export class ItemsFormComponent implements ControlValueAccor, OnInit {

public form: FormArray;

public items: string = ['foo', 'bar', 'baz'];

constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.array(this.items.map((item) => new FormControl(item)));

this.form.valueChanges
.debounceTime(200)
.subscribe((items: string) => {
this.onChangeFn(items);
});
}
}


But then, I get a Template parsing error with



<ol [formArray]="form">
...
</ol>


Can't bind to 'formArray' since it isn't a known property of 'ol'



I DID include the FormsModule and the ReactiveFormsModule in my Feature Module. Any other form based on FormGroup work.



It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway.



So is there no way to use a FormArray as the top level form? Ideally, I'd like to avoid creating a FormGroup with a single FormArray in it.










share|improve this question













I'm using @ngular/core 6.1.1 and @angular/forms 6.1.1



I'm trying to write a ControlValueAccessor which will manage an array of values.



I'm using reactive forms and declaring my form like this:



export class ItemsFormComponent implements ControlValueAccor, OnInit {

public form: FormArray;

public items: string = ['foo', 'bar', 'baz'];

constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.array(this.items.map((item) => new FormControl(item)));

this.form.valueChanges
.debounceTime(200)
.subscribe((items: string) => {
this.onChangeFn(items);
});
}
}


But then, I get a Template parsing error with



<ol [formArray]="form">
...
</ol>


Can't bind to 'formArray' since it isn't a known property of 'ol'



I DID include the FormsModule and the ReactiveFormsModule in my Feature Module. Any other form based on FormGroup work.



It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway.



So is there no way to use a FormArray as the top level form? Ideally, I'd like to avoid creating a FormGroup with a single FormArray in it.







angular angular-forms






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 12:59









paztek

9116




9116












  • "It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway." Why? For me is correct
    – Eliseo
    Nov 10 at 13:36










  • OK, it builds in prod with <ol [formGroup]="form"> but it still looks like a hack to me..
    – paztek
    Nov 10 at 13:49


















  • "It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway." Why? For me is correct
    – Eliseo
    Nov 10 at 13:36










  • OK, it builds in prod with <ol [formGroup]="form"> but it still looks like a hack to me..
    – paztek
    Nov 10 at 13:49
















"It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway." Why? For me is correct
– Eliseo
Nov 10 at 13:36




"It kinda works if I do <ol [formGroup]="form"> but it seems like a weird hack and the validation seems broken. And I'm afraid it will break when building for prod anyway." Why? For me is correct
– Eliseo
Nov 10 at 13:36












OK, it builds in prod with <ol [formGroup]="form"> but it still looks like a hack to me..
– paztek
Nov 10 at 13:49




OK, it builds in prod with <ol [formGroup]="form"> but it still looks like a hack to me..
– paztek
Nov 10 at 13:49












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










Yes you can use FormArray as the top level form,



place: FormArray = new FormArray([
new FormControl('SF'),
new FormControl('NY'),
]);


And in the template,



<div *ngFor="let c of place.controls; index as i">
<input [formControl]="c" placeholder="c">
</div>

<ng-container *ngFor="let c of place.controls">
<pre>{{this.c.value | json}}</pre>
</ng-container>


Here is the working demo on stackblitz






share|improve this answer




























    up vote
    0
    down vote













    What you have done so far is pretty close except wrong form object reference.



    Your modified code



    html



    <hello name="{{ name }}"></hello>
    <p>
    Start editing to see some magic happen :)
    </p>
    <div *ngFor="let c of form.controls; index as i">
    <input [formControl]="c" placeholder="c">
    </div>

    <ng-container *ngFor="let c of form.controls">
    <pre>{{this.c.value | json}}</pre>
    </ng-container>


    ts



    export class AppComponent {

    public form: FormArray;

    public items: string = ['foo', 'bar', 'baz'];

    constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.array(
    this.items.map((item) => new FormControl(item))
    );

    this.form.valueChanges.subscribe(changes=>{
    console.log("changes to form ", changes);
    });
    }
    }


    Working demo is here - https://stackblitz.com/edit/angular-em7j9h




    Note : you should ignore FormArray in html otherwise you need will be forced to have FormGroup.







    share|improve this answer





















    • How is my answer different than yours?
      – anonymous
      Nov 10 at 19:14











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239189%2fis-there-a-way-to-use-a-formarray-as-the-top-level-form%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    Yes you can use FormArray as the top level form,



    place: FormArray = new FormArray([
    new FormControl('SF'),
    new FormControl('NY'),
    ]);


    And in the template,



    <div *ngFor="let c of place.controls; index as i">
    <input [formControl]="c" placeholder="c">
    </div>

    <ng-container *ngFor="let c of place.controls">
    <pre>{{this.c.value | json}}</pre>
    </ng-container>


    Here is the working demo on stackblitz






    share|improve this answer

























      up vote
      2
      down vote



      accepted










      Yes you can use FormArray as the top level form,



      place: FormArray = new FormArray([
      new FormControl('SF'),
      new FormControl('NY'),
      ]);


      And in the template,



      <div *ngFor="let c of place.controls; index as i">
      <input [formControl]="c" placeholder="c">
      </div>

      <ng-container *ngFor="let c of place.controls">
      <pre>{{this.c.value | json}}</pre>
      </ng-container>


      Here is the working demo on stackblitz






      share|improve this answer























        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        Yes you can use FormArray as the top level form,



        place: FormArray = new FormArray([
        new FormControl('SF'),
        new FormControl('NY'),
        ]);


        And in the template,



        <div *ngFor="let c of place.controls; index as i">
        <input [formControl]="c" placeholder="c">
        </div>

        <ng-container *ngFor="let c of place.controls">
        <pre>{{this.c.value | json}}</pre>
        </ng-container>


        Here is the working demo on stackblitz






        share|improve this answer












        Yes you can use FormArray as the top level form,



        place: FormArray = new FormArray([
        new FormControl('SF'),
        new FormControl('NY'),
        ]);


        And in the template,



        <div *ngFor="let c of place.controls; index as i">
        <input [formControl]="c" placeholder="c">
        </div>

        <ng-container *ngFor="let c of place.controls">
        <pre>{{this.c.value | json}}</pre>
        </ng-container>


        Here is the working demo on stackblitz







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 10 at 14:00









        anonymous

        185115




        185115
























            up vote
            0
            down vote













            What you have done so far is pretty close except wrong form object reference.



            Your modified code



            html



            <hello name="{{ name }}"></hello>
            <p>
            Start editing to see some magic happen :)
            </p>
            <div *ngFor="let c of form.controls; index as i">
            <input [formControl]="c" placeholder="c">
            </div>

            <ng-container *ngFor="let c of form.controls">
            <pre>{{this.c.value | json}}</pre>
            </ng-container>


            ts



            export class AppComponent {

            public form: FormArray;

            public items: string = ['foo', 'bar', 'baz'];

            constructor(private formBuilder: FormBuilder) {
            this.form = this.formBuilder.array(
            this.items.map((item) => new FormControl(item))
            );

            this.form.valueChanges.subscribe(changes=>{
            console.log("changes to form ", changes);
            });
            }
            }


            Working demo is here - https://stackblitz.com/edit/angular-em7j9h




            Note : you should ignore FormArray in html otherwise you need will be forced to have FormGroup.







            share|improve this answer





















            • How is my answer different than yours?
              – anonymous
              Nov 10 at 19:14















            up vote
            0
            down vote













            What you have done so far is pretty close except wrong form object reference.



            Your modified code



            html



            <hello name="{{ name }}"></hello>
            <p>
            Start editing to see some magic happen :)
            </p>
            <div *ngFor="let c of form.controls; index as i">
            <input [formControl]="c" placeholder="c">
            </div>

            <ng-container *ngFor="let c of form.controls">
            <pre>{{this.c.value | json}}</pre>
            </ng-container>


            ts



            export class AppComponent {

            public form: FormArray;

            public items: string = ['foo', 'bar', 'baz'];

            constructor(private formBuilder: FormBuilder) {
            this.form = this.formBuilder.array(
            this.items.map((item) => new FormControl(item))
            );

            this.form.valueChanges.subscribe(changes=>{
            console.log("changes to form ", changes);
            });
            }
            }


            Working demo is here - https://stackblitz.com/edit/angular-em7j9h




            Note : you should ignore FormArray in html otherwise you need will be forced to have FormGroup.







            share|improve this answer





















            • How is my answer different than yours?
              – anonymous
              Nov 10 at 19:14













            up vote
            0
            down vote










            up vote
            0
            down vote









            What you have done so far is pretty close except wrong form object reference.



            Your modified code



            html



            <hello name="{{ name }}"></hello>
            <p>
            Start editing to see some magic happen :)
            </p>
            <div *ngFor="let c of form.controls; index as i">
            <input [formControl]="c" placeholder="c">
            </div>

            <ng-container *ngFor="let c of form.controls">
            <pre>{{this.c.value | json}}</pre>
            </ng-container>


            ts



            export class AppComponent {

            public form: FormArray;

            public items: string = ['foo', 'bar', 'baz'];

            constructor(private formBuilder: FormBuilder) {
            this.form = this.formBuilder.array(
            this.items.map((item) => new FormControl(item))
            );

            this.form.valueChanges.subscribe(changes=>{
            console.log("changes to form ", changes);
            });
            }
            }


            Working demo is here - https://stackblitz.com/edit/angular-em7j9h




            Note : you should ignore FormArray in html otherwise you need will be forced to have FormGroup.







            share|improve this answer












            What you have done so far is pretty close except wrong form object reference.



            Your modified code



            html



            <hello name="{{ name }}"></hello>
            <p>
            Start editing to see some magic happen :)
            </p>
            <div *ngFor="let c of form.controls; index as i">
            <input [formControl]="c" placeholder="c">
            </div>

            <ng-container *ngFor="let c of form.controls">
            <pre>{{this.c.value | json}}</pre>
            </ng-container>


            ts



            export class AppComponent {

            public form: FormArray;

            public items: string = ['foo', 'bar', 'baz'];

            constructor(private formBuilder: FormBuilder) {
            this.form = this.formBuilder.array(
            this.items.map((item) => new FormControl(item))
            );

            this.form.valueChanges.subscribe(changes=>{
            console.log("changes to form ", changes);
            });
            }
            }


            Working demo is here - https://stackblitz.com/edit/angular-em7j9h




            Note : you should ignore FormArray in html otherwise you need will be forced to have FormGroup.








            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 10 at 17:08









            Sunil Singh

            4,6811624




            4,6811624












            • How is my answer different than yours?
              – anonymous
              Nov 10 at 19:14


















            • How is my answer different than yours?
              – anonymous
              Nov 10 at 19:14
















            How is my answer different than yours?
            – anonymous
            Nov 10 at 19:14




            How is my answer different than yours?
            – anonymous
            Nov 10 at 19:14


















             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239189%2fis-there-a-way-to-use-a-formarray-as-the-top-level-form%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Full-time equivalent

            Bicuculline

            さくらももこ