Ke Vin Ke Vin - 7 months ago 32
JSON Question

how to build JSON data using ngModel in form and table with ngFor in Angular?

How to build a JSON data using ngModel which is the component is inside form and the table is outside form, which is i have ngModel repeated using ngFor in the table. Here is how my html looked like :

app.component.html :

<div>
<form>
<div class="form-group row">
Nama Role : <input type="text" [(ngModel)]="nama_role" [ngModelOptions]="{standalone: true}" class="form-control" placeholder="Nama Role" pattern="[a-zA-Z-0-9. ]+">
</div>
</form>

<div>
Pilih Hak :
<table class="mytable">
<tr>
<th>No</th>
<th>Kode Aplikasi</th>
<th>Nama Aplikasi</th>
<th>View?</th>
<th>Insert?</th>
<th>Edit?</th>
<th>Delete?</th>
</tr>
<tr *ngFor="let sources of source; let a=index">
<td>{{a + 1}}</td>
<td>{{sources.KODE_APPLICATION}}</td>
<td>{{sources.NAMA_APPLICATION}}</td>
<td><input type="checkbox" [(ngModel)]="sources.hak_akses" (change)="toggle($event)" /> {{sources.HAK_AKSES}}</td>
<td><input type="checkbox" [(ngModel)]="sources.hak_insert" (change)="toggle($event)" />{{sources.HAK_INSERT}}</td>
<td><input type="checkbox" [(ngModel)]="sources.hak_edit" (change)="toggle($event)" />{{sources.HAK_EDIT}}</td>
<td><input type="checkbox" [(ngModel)]="sources.hak_delete" (change)="toggle($event)" />{{sources.HAK_DELETE}}</td>
</tr>
</table>
</div>

<div class="row show-grid">
<button class="btn btn-primary" (click)="save()">Save</button>
</div>

</div>


and here is my app.component.ts

export class frmInputMasterRole {

public sKodeRole: any;
sStorage:any;
hak_akses:any;
hak_insert:any;
hak_edit:any;
hak_delete:any;
private busyloadevent: IBusyConfig = Object.assign({}, BUSY_CONFIG_DEFAULTS);
marked = false;

constructor(private frmInputMasterRoleService: FrmInputMasterRoleService, protected router: Router) {
this.sKodeRole = 'Auto Generated';
this.sStorage = sessionStorage.getItem('mAuth');
this.sStorage = JSON.parse(this.sStorage);

this.busyloadevent.busy = this.frmInputMasterRoleService.getListRoleDetail().then(
data => {
this.source = data;
console.log(data);
for (var i of this.source) {
this.hak_akses = i.HAK_AKSES;
}
},
err => {
console.log(err);
}
}
);

}

save(){
console.log(this.hak_akses);
}

toggle(e){
console.log(e.target.checked)
}

cancel(){
this.router.navigate(['/pages/master/rolelist']);
}

}


and here is my JSON data when consume my REST API, which is looped with ngFor in source type :

[
{
"No":"1",
"KODE_APPLICATION":"APPL00001",
"NAMA_APPLICATION":"Master Bass",
"HAK_AKSES":0,
"HAK_INSERT":0,
"HAK_EDIT":0,
"HAK_DELETE":0
},
{
"No":"2",
"KODE_APPLICATION":"APPL00002",
"NAMA_APPLICATION":"Master Customer",
"HAK_AKSES":0,
"HAK_INSERT":0,
"HAK_EDIT":0,
"HAK_DELETE":0
},
{
"No":"3",
"KODE_APPLICATION":"APPL00003",
"NAMA_APPLICATION":"Master Teknisi",
"HAK_AKSES":0,
"HAK_INSERT":0,
"HAK_EDIT":0,
"HAK_DELETE":0
}
]


what i want is i want to build JSON data that looked like this when the last row is checked :

{
"nama_role":test,
"details": [{
"KODE_APPLICATION":"APPL00003",
"NAMA_APPLICATION":"Master Teknisi",
"HAK_AKSES":1,
"HAK_INSERT":0,
"HAK_EDIT":0,
"HAK_DELETE":0
}]
}


how do i do this? i dunno where to start since there is a table with ngModel that looped with ngFor

Answer Source

Code is attached below:

    @Component({
    selector: 'my-app',
    template: `<form>
                    <div class="form-group row">
                        Nama Role : <input type="text" [(ngModel)]="nama_role" [ngModelOptions]="{standalone: true}" class="form-control" placeholder="Nama Role" pattern="[a-zA-Z-0-9. ]+">
                    </div>
               </form>

               <table>
                    <tr>
                        <th>No</th>
                        <th>Kode Aplikasi</th>
                        <th>Nama Aplikasi</th>
                        <th>View?</th>
                        <th>Insert?</th>
                        <th>Edit?</th>
                        <th>Delete?</th>
                    </tr>
                    <tr *ngFor="let sources of source; let a=index">
                        <td>{{sources.KODE_APPLICATION}}</td>
                        <td>{{sources.NAMA_APPLICATION}}</td>
                        <td><input type="checkbox"  [checked]="sources.HAK_AKSES" [(ngModel)]="sources.HAK_AKSES" (change)="toggle(a, sources.HAK_AKSES, \'HAK_AKSES\')"/> {{sources.HAK_AKSES}}</td>
                        <td><input type="checkbox" [checked]="sources.HAK_INSERT" [(ngModel)]="sources.HAK_INSERT"  (change)="toggle(a, sources.HAK_INSERT, \'HAK_INSERT\')" />{{sources.HAK_INSERT}}</td>
                        <td><input type="checkbox" [checked]="sources.HAK_EDIT"  [(ngModel)]="sources.HAK_EDIT" (change)="toggle(a, sources.HAK_EDIT, \'HAK_EDIT\')" />{{sources.HAK_EDIT}}</td>
                        <td><input type="checkbox" [checked]="sources.HAK_DELETE" [(ngModel)]="sources.HAK_DELETE" (change)="toggle(a, sources.HAK_DELETE, \'HAK_DELETE\')" />{{sources.HAK_DELETE}}</td>
                    </tr>
                </table>

                <div class="row show-grid">
                    <button class="btn btn-primary" (click)="save()">Save</button>
                </div> 
                <custom-comp [myFunc]="handleClick()"></custom-comp>
              `
})

export class MainComponent {

    source = [];

    ngOnInit() {

        this.source = [{
          "No":"1",
          "KODE_APPLICATION":"APPL00001",
          "NAMA_APPLICATION":"Master Bass",
          "HAK_AKSES":1,
          "HAK_INSERT":1,
          "HAK_EDIT":1,
          "HAK_DELETE":0
       },
       {
          "No":"2",
          "KODE_APPLICATION":"APPL00002",
          "NAMA_APPLICATION":"Master Customer",
          "HAK_AKSES":0,
          "HAK_INSERT":0,
          "HAK_EDIT":0,
          "HAK_DELETE":0
       },
       {
          "No":"3",
          "KODE_APPLICATION":"APPL00003",
          "NAMA_APPLICATION":"Master Teknisi",
          "HAK_AKSES":1,
          "HAK_INSERT":0,
          "HAK_EDIT":0,
          "HAK_DELETE":0
       }
    ];
    }

    save() {
        let payload = {
            "nama_role": this.nama_role,
            "details": this.source
        };

        console.log(payload);
    }

    toggle(index, val, key) {
        this.source[index][key] = val ? 1 : 0;
    }
}

Cheers!