Angular 4 reactive form - FormArray Within FormArray unable to get path -
for few days ive been trying create form alow user create product, , @ same time variations of product may have different price parent product. eg large widget £10, small widget £5. end every time formarray within formarray, in other word have product array of variations, variations have price, have array of attributes well. problem comes when try add controls, can variation price show fine, can't path in order add variations.attributes controls, error ngfor working arrays not [object, object] or control null... i've had more errors can remember! anyway onto code, has been re-written alot, , worse started out!
first form in oninit:
ngoninit() { this.getattributes(); // attribute categories this.form = this.fb.group({ name: [''], price: [''], description: [''], stockref: [''], attributes: this.fb.array([{ attributecategoryid: [''], name: [''], }]), variations: this.fb.array([{ vprice: this.vprice, vattributes: this.vattributes }]), }); }
the section adding , removing attributes master product, works fine:
addattribute(id: any, name: any) { if (!id.value || !name.value) return; this.attributes = <formarray>this.form.get('attributes'); var newattribute = this.fb.group({ attributecategoryid: [id.value], name: [name.value], }); this.newlist.push({ name: [name.value].tostring(), attributecategoryid: [id.value].tostring() }); this.attributes.push(newattribute); id.value = ''; name.value = ''; } removeattr(i: any) { this.attributes.removeat(i); this.list2 = []; this.newlist.splice(i, 1); }
the part add variations, works, still has code used try , copy attributes added main product, variation, worked think, couldn't access values in order display them, variations.attributes didn't work path.
initvariation() { let v = this.fb.group({ price: [''], vattributes: this.attributes //copies main attributes }); this.attributes.reset(); //reset main attributes return v; //belong variation } addnewvar() { const control = <formarray>this.form.controls['variations']; control.push(this.initvariation()); }
the part adds attributes variation, not work, , i'm having issues in component.ts
addattrrow() { const control = <formarray>this.form.controls['variations.vattributes'] control.push(this.initvattr()) } initvattr() { let va = this.fb.group({ vattributecategoryid: [''], vname: [''] }) return va; }
finally, html more of mess lol:
<h1>new product</h1> <form [formgroup]="form" (ngsubmit)="save()"> <div class="row"> <div class="col-md-6 col-sm-12"> <div class="form-group"> <label>product name</label> <div *ngif="!form.get('name').valid" class="alert alert-danger"> {{ form.get('name').geterror('remote') }} </div> <input [(ngmodel)]="name" type="text" formcontrolname="name" class="form-control"> </div> </div> </div> <div class="row"> <div class="col-md-6 col-sm-12"> <div class="form-group"> <label>price</label> <div *ngif="!form.get('price').valid" class="alert alert-danger"> {{ form.get('price').geterror('remote') }} </div> <input [(ngmodel)]="price" type="number" formcontrolname="price" class="form-control"> </div> </div> </div> <div class="row"> <div class="col-md-6 col-sm-12"> <div class="form-group"> <label>product description</label> <div *ngif="!form.get('description').valid" class="alert alert-danger"> {{ form.get('description').geterror('remote') }} </div> <textarea formcontrolname="description" class="form-control"></textarea> </div> </div> </div> <div class="row"> <div class="col-md-6 col-sm-12"> <div> <h4>attributes</h4> <div class="form-inline" > <div class="form-group"> <div formarrayname="attributes"> <select #ac name="attributecategoryid"> <option value="" selected>category</option> <option *ngfor="let of attriblist;let = index" value="{{a.id}}">{{a.name}}</option> </select> <input #a name="name" placeholder="attribute name" /> </div> </div> <button type="button" class="btn btn-default" (click)="addattribute(ac,a)">add attribute</button> </div> <br> <table class="table-bordered table table-striped"> <thead> <tr> <th>attr. category</th> <th>attr.</th> <th><button type="button" (click)="addnewvar()" class="btn btn-primary">add variation</button></th> </tr> </thead> <tbody> <tr *ngfor="let of form.value.attributes; let = index;" > <td *ngif="i > 0">{{a.attributecategoryid}}</td> <td *ngif="i > 0">{{a.name}}</td> <td *ngif="i > 0"><button (click)="removeattr(i)" class="btn btn-danger">x</button></td> </tr> </tbody> </table> </div> </div> </div> <!--variations start--> <div class="row" formarrayname="variations"> <div *ngfor="let variation of form.controls.variations.controls; let i=index" [formgroupname]="i"> <h5>variation #{{ + 1 }}</h5> <p></p> <div class="form-group"> <label>variation price</label> <input name="vprice" style="max-width:50px" class="form-control"> </div> <table> <thead> <tr> <th>attr. category</th> <th>attr.</th> <th><button class="btn btn-success" (click)="addattrrow()">+</button></th> </tr> </thead> <tbody name="vattributes"> <tr *ngfor="let attribute of variation.get('vattributes'); let ii = index;"> <td><input type="text" name="vattributecateforyid" /></td> <td><input type="text" name="vname" /></td> <td><button (click)="removevattr(ii)" class="btn btn-danger">x</button></td> </tr> </tbody> </table> <button class="btn btn-danger" (click)="removevariation(i)">delete</button> </div> </div> <!--variations end--> <br> <p> <button type="submit" class="btn btn-primary">save</button> </p> </form>
i see lot of mistakes in code.
for example
1) should aware need not forget index when deal getting control formarray
so instead of
const control = <formarray>this.form.controls['variations.vattributes'];
we should use
addattrrow(index) { const control = <formarray>this.form.get(['variations', index, 'vattributes']);
2) if don't specify type button
have submit
default value.
<button class="btn btn-success" (click)="addattrrow()">+</button>
and can lead unpredictable situations.
so try specify type="button"
3) iterate on object
*ngfor="let attribute of variation.get('vattributes');
while need iterate on array
*ngfor="let variation of form.controls.variations.controls;
i created plunker example can realize did wrong
Comments
Post a Comment