1

I've been stuck on this problem for a while. I have a data table in my application and there are some fields the user can modify for each record in the table.

The user is able to then click a button and save all the changes which will fire off a query to the database to update the records. Instead of passing every single record in my table (the data is just an array), I want to just pass the records that have been modified.

For example: Original players[0]:

{ "name": "player 1", "joinDate": "06/25/2018", "ppg": "28.5" }

After user modifies it:

{ "name": "player 1", "joinDate": "06/25/2018", "ppg": "30.9" }

Ideally I just want to send that one record or n amount of records that have been modified. I've seen this solution Angular update object in object array but it seems like it is for NgClass, NgStyle etc's.

Would appreciate some help.

2
  • when using Angular form you should be able to monitor the dirty-ness of each input and that helps in determining which fields have been altered. Commented Jun 25, 2018 at 23:49
  • @HarryNinh I'm not using a form its just a simple input field. Also regarding dirty-ness I thought of that too but it might not be fully helpful because someone may change the data and then change it back to what it originally was, and it would still be marked as dirty right? Commented Jun 26, 2018 at 0:00

2 Answers 2

0

You can use Set in Javascript to store which changes from user.

export class AppComponent {
  data = [
    { name: 'Kean', age: 24 },
    { name: 'Messi', age: 31 },
    { name: 'Salah', age: 23 },
    { name: 'Ronaldo', age: 33 },
  ]
  yourChanges = new Set();
  yourArr = [];
  change(item) {
    this.yourChanges.add(item);
    this.yourArr = Array.from(this.yourChanges);
  }
}
<table>
  <tr *ngFor="let item of data">
    <td>
      <input (change)="change(item)" [(ngModel)]="item.name">
    </td>
    <td>
      <input (change)="change(item)" [(ngModel)]="item.age">
    </td>
  </tr>
</table>
{{yourArr| json}}

Result: Just only change for Kean and Salah only, if you change Kean again the Set in Javascript will be distinc the duplicate object.

result

Sign up to request clarification or add additional context in comments.

1 Comment

thanks your answer gave me an idea of what I had to do
0

Ok well I figured it out, not sure if it's the best solution. It worked though. I used lodash for this. Basically the idea is to create an array which is the original copy of the area your trying to track for changes, and then compare the original array with the current array that the user is able to change the data with and then find the difference.

Example:

originalUsers:

[
  {"firstName": "John", "lastName": "Smith" },
  { "firstName": "Jane", "lastName": "Smith" },
]

HTML:

<your_respective_table *ngFor="let user of users">
  <input type="text" [(ngModel)]="user.lastName">
</your_respective_table>

Lets say the user changes the firstName on John Smith, to John Doe

The usersArray would look like:

[
  {"firstName": "John", "lastName": "Doe" },
  { "firstName": "Jane", "lastName": "Smith" },
]

Typescript (your component):

import { cloneDeep as _cloneDeep, differenceWith as _differenceWith, isEqual as _isEqual } from 'lodash';

.... // Component declaration
.... 
// where ever your getting or subscribing to your array after when the stream is complete

this.originalUsers = _cloneDeep(this.users);
...
...

getChanges() {
  let changedUsers = [];
  changedUsers = _differenceWith(this.users, this.originalUsers, _isEqual);
}

The expected output from getChanges() will give only the user objects inside the users array that have changed so in this case the output would be:

changedUsers = [ {"firstName": "John", "lastName": "Doe" } ]

Keep in mind the order matters for _differenceWith when you pass in the arrays as arguments to the method. You want to keep the array your tracking as the first argument and the original copy of the array as the second argument.

Hope this helps anyone in the future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.