How do I add functionality to update multiple records at a time to json from angular

烈酒焚心 提交于 2020-12-15 03:47:29

问题


I am using angular httpclient to do the crud operations. I have an edit option for every record but I wanted to update multiple records at a time by selecting the checkbox and click on the update button.

Can you please look into it and help me to achieve the same to have a checkbox before impact for every row and select click on the edit button, select updated option n click on update button to update all those selected records.

Also, If I can get the count of how many applicable, not applicable, and FYI out of those records that would be really helpful.

common.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CommonService {

  constructor(private http:HttpClient) { }

  createUser(user: any) {
    return this.http.post("http://localhost:3000/users", user);
  }
  getAllUser() {
    return this.http.get("http://localhost:3000/users");
  }
  updateUser(user: any): Observable<any> {
    return this.http.put("http://localhost:3000/users/" + user.id, user);
  }
  deleteUser(user: any) {
    return this.http.delete("http://localhost:3000/users/" + user.id);
  }
}

app.component.ts

    import { Component } from '@angular/core';
import { CommonService } from './common.service';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent {
  title = 'db-poc1';
  allUser: any;
  isEdit = false;
  isView = false;
  isBatchEdit = false;
  totalRecords: any;
  page: Number = 1;
  currentImpact: string = '';

  isNonTrade: boolean = false
  checkAllNonTrades: boolean = false

  changeTradesByCategory(event) {
    if (event.target.name == 'nontrades') {
      this.isNonTrade = true
    }

    if (this.isNonTrade && this.checkAllNonTrades) {
      event.target.checked = true
    }
  }

  userObj = {
    id: '', first_name: '', last_name: '', email: '', gender: '', ip_address: '', impact: ''
  }

  impactCount = {
    applicable: 0, notapplicable: 0, fyi: 0 
  }

  batchUpdateUsers = [];

  constructor(private commonService: CommonService) {}

  ngOnInit() {
    this.getLatestUser();
  }
  
  checkboxClicked() {
    this.batchUpdateUsers = this.allUser.filter(row => row.checked);
    this.isView  = false;
    this.isBatchEdit = this.batchUpdateUsers.length > 0;
    this.currentImpact = this.userObj.impact;
  }

  selectAllClicked(event) {
    this.isBatchEdit = true;
    const checked = event.target.checked;
    this.allUser.forEach(item => item.selected = checked);
    this.batchUpdateUsers = checked;
    this.isBatchEdit = checked > 0;
    this.currentImpact = this.userObj.impact;
  }

  addUser(formObj: any) {
    this.commonService.createUser(formObj).subscribe((response) => {
      this.getLatestUser();
    })
  }

  getLatestUser() {
    this.commonService.getAllUser().subscribe((response) => {
      this.allUser = response;
      this.totalRecords = this.allUser.length;
      this.getApplicableCounts();
      this.allUser.forEach(row => row.checked = false);
    })
  }

  getApplicableCounts() {
    this.impactCount = {applicable: 0,notapplicable: 0,fyi: 0}
    this.allUser.forEach(row => {
      if (row.impact === 'Applicable') {
        this.impactCount.applicable++;
      } else if (row.impact === 'Not Applicable') {
         this.impactCount.notapplicable++;
      } else if (row.impact === 'FYI') {
        this.impactCount.fyi++;
      }
    });
  }

  editUser(user: any) {
    this.isEdit = true;
    this.userObj = user;
    this.allUser.forEach(user => user.checked = false);
    this.currentImpact = user.impact;
  }

  deleteUser(user: any) {
    this.commonService.deleteUser(user).subscribe(() => {      
      this.getLatestUser();
    })
  }

  updateUser() {
    this.isEdit = !this.isEdit;
    this.userObj.impact = this.currentImpact;
    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();
    })
    this.getApplicableCounts();
  }

  cancelEdit() {
    this.isEdit = false;
    this.isView = false;    
  }

  viewUser(user: any) {
    this.isView = true;
    this.userObj = user;
  }

  cancelBatchEdit() {
    this.isBatchEdit = false;
    this.allUser.forEach(user => {user.checked = false});
  }

  batchUpdateUser() {
    this.isBatchEdit = false;
    const batchUpdateUserList = [];
    this.allUser.forEach(user => {
      if (user.checked) {
        user.impact = this.currentImpact
        batchUpdateUserList.push(user);
        user.checked = false;
        this.commonService.updateUser(user).subscribe(() => {
          this.getLatestUser();
        })
      }
    });

    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();
    })

    this.getApplicableCounts();
  }

}

app.component.html

    <div class="container-fluid">
  <div class="text-right toal-records">Total: {{totalRecords}}</div>

  <div class="skills">
    <ul class="labels">
      <li>Applicable</li>
      <li>Not Applicable</li>
      <li>FYI</li>
    </ul>
    <ul class="lines">
      <li class="line l--0"><span class="line__label">0</span></li>
      <li class="line l--1"><span class="line__label">1</span></li>
      <li class="line l--2"><span class="line__label">2</span></li>
      <li class="line l--3"><span class="line__label">3</span></li>
      <li class="line l--4"><span class="line__label">4</span></li>
      <li class="line l--5"><span class="line__label">5</span></li>
      <li class="line l--6"><span class="line__label">6</span></li>
      <li class="line l--7"><span class="line__label">7</span></li>
      <li class="line l--8"><span class="line__label">8</span></li>
      <li class="line l--9"><span class="line__label">9</span></li>
    </ul>
    <div class="charts">
      <div class="chart chart--dev">
        <ul class="chart--horiz">
          <li class="chart__bar" [style.width]="impactCount.applicable * 10 + '%'"></li>
          <li class="chart__bar" [style.width]="impactCount.notapplicable * 10 + '%'"></li>
          <li class="chart__bar" [style.width]="impactCount.fyi * 10 + '%'"></li>
        </ul>
      </div>
    </div>
  </div>

  <table class="table table-sm table-responsive">
    <thead>
      <tr>
        <th>
          <input type="checkbox" name="allNonTrades" (change)="selectAllClicked($event)">        
        </th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Email</th>
        <th>Gender</th>
        <th>ID Address</th>
        <th>Impact</th>
        <!-- <th></th> -->
      </tr>
    </thead>
    <tbody>
      <tr class="record-row" (click)="viewUser(user)" *ngFor="let user of allUser | paginate: { id: 'listing_pagination', itemsPerPage: 10, currentPage: page, totalItems: totalRecords }">
        <td><input *ngIf="!isEdit"  name="nontrades" [checked]="user.selected" (change)="changeTradesByCategory($event)" [(ngModel)]="user.checked" type="checkbox" (change)="checkboxClicked()"></td>
        <td>{{user.first_name}}</td>
        <td>{{user.last_name}}</td>
        <td>{{user.email}}</td>
        <td>{{user.gender}}</td>
        <td>{{user.ip_address}}</td>
        <td>{{user.impact}}</td>
        <!-- <td>
          <button *ngIf="!isEdit" class="btn btn-primary btn-sm" (click)="editUser(user)" data-toggle="modal" data-target="#exampleModel">Edit</button>
        </td> -->
      </tr>
    </tbody>
  </table>
  
  <pagination-controls id="listing_pagination" directionLinks="true" (pageChange)="page = $event"></pagination-controls>
  
  <div *ngIf="isView" class="view-details">
    <ul>
      <li>First Name <br />{{userObj.first_name}}</li>
      <li>Last Name <br />{{userObj.last_name}}</li>
      <li>Email <br />{{userObj.email}}</li>
      <li>Gender <br />{{userObj.gender}}</li>
      <li>IP Address <br />{{userObj.ip_address}}</li>
      <li>Impact <br />{{userObj.impact}}</li>
    </ul>
  </div>

  <form #myForm="ngForm">
    <div class="form-group">
      <select name="impact" [disabled]="!isBatchEdit" class="form-control form-control-sm" [(ngModel)]="currentImpact">
        <option value="" disabled selected>Change Impact</option>          
        <option>Applicable</option>
        <option>Not Applicable</option>
        <option>FYI</option>
      </select>
    </div>
    <button type="button" [disabled]="!isBatchEdit" (click)="batchUpdateUser(); myForm.reset()" class="btn btn-success btn-sm btn-update mr-2">
      Update
      </button>
    <button type="button" [disabled]="!isBatchEdit" (click)="cancelBatchEdit(); myForm.reset()" class="btn btn-secondary btn-sm">Cancel</button>
  </form>

  <!-- <div *ngIf="isEdit">
    <form #myForm="ngForm">
      <div class="form-group">
        <select name="impact" id="" class="form-control form-control-sm" [(ngModel)]="currentImpact">
          <option>Applicable</option>
          <option>Not Applicable</option>
          <option>FYI</option>
        </select>
      </div>
      <button type="button" (click)="updateUser()" class="btn btn-success btn-sm btn-update mr-2" *ngIf="isEdit">Update</button>
      <button type="button" (click)="cancelEdit()" class="btn btn-secondary btn-sm">Cancel</button>
    </form>
  </div> -->
</div>

db.json

{
"users": [
{
  "id": 1,
  "first_name": "Kunal",
  "last_name": "Vijan",
  "email": "vijan87@gmail.com",
  "gender": "Male",
  "ip_address": "1.1.1.1",
  "impact": "Applicable"
},
{
  "id": 2,
  "first_name": "Kunal",
  "last_name": "Vijan",
  "email": "vijan87@gmail.com",
  "gender": "Male",
  "ip_address": "1.1.1.1",
  "impact": "Not Applicable"
},
{
  "id": 3,
  "first_name": "Kunal",
  "last_name": "Vijan",
  "email": "vijan87@gmail.com",
  "gender": "Male",
  "ip_address": "1.1.1.1",
  "impact": "FYI"
}
]
}

回答1:


The problem is in your batch update function. You populate the batchUpdateUserList but then you send the this.userObj to the server. The this.userObj is a single record and is not going to give you the batch update you want.

  batchUpdateUser() {
    this.isBatchEdit = false;
    const batchUpdateUserList = []; // objects to 
    this.allUser.forEach(user => {
      if (user.checked) {
        user.impact = this.currentImpact
        batchUpdateUserList.push(user);
        user.checked = false;
      }
    });

    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();      
    }); 
  }

I had a comment in the function that was saying you need to create a new this.commonService.batchUpdate() call for the server, but if is not possible to create a new call that sends a list of users for update, then you can do the following

  batchUpdateUser() {
    this.isBatchEdit = false;
    const batchUpdateUserList = []; // objects to 
    this.allUser.forEach(user => {
      if (user.checked) {
        user.impact = this.currentImpact
        batchUpdateUserList.push(user);
        user.checked = false;

        this.commonService.updateUser(user).subscribe();
      }
    });

    this.getLatestUser();   
  }

but it is not recommended because this is going to be slow and buggy for large updates. You can use a forkJoin to solve this issue, but it would prefered if you would create a new service that sends a list to the server for update. You can look at the stackblitz for the example but I didn't update it with this code because the project isn't connected to a server.



来源:https://stackoverflow.com/questions/65214192/how-do-i-add-functionality-to-update-multiple-records-at-a-time-to-json-from-ang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!