Skip to content
Advertisement

how to avoid the updated value to be binded to other array using angular13

i am working on angular13, here i have button to move items from left to right. now once the item is moved from left to right and if i edit the same item under right side, the edited value is updated in left side array as well.

HTML:

<div class="card">
  <div class="card-header" id="headingBasicAgentsGroupView">
    <a
      href="javascript:void(0);"
      class="d-block h5 mb-0"
      data-target="#basicAgentsGroupView"
      aria-expanded="false"
      aria-controls="basicAgentsGroupView"
      >Group View</a
    >
  </div>
  <div
    class=""
    id="basicAgentsGroupView"
    aria-labelledby="headingBasicAgentsGroupView"
    data-parent="#basicTabAccordion"
  >
    <div class="card-body" id="agents-group-view">
      <div class="row">
        <div class="col">
          <div class="form-group">
            <h6 class="font-weight-bold">Group</h6>
          </div>
        </div>
        <div class="col-2"></div>
        <div class="col">
          <div class="form-group">
            <h6 class="font-weight-bold">Not in Group</h6>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col">
          <div class="card shadow-sm border-0 swap-list list-left">
            <div class="card-header border-bottom-0 rounded-top">
              <div class="row">
                <div class="col d-flex align-items-center">
                  <input
                    type="text"
                    name="SearchDualList"
                    class="form-control"
                    placeholder="Search"
                  />
                </div>
              </div>
            </div>
            <div class="card-body overflow-auto py-0">
              <ul
                class="list-group list-group-flush"
                *ngFor="let child of agentInView"
                name="agentInGroup"
              >
                <li
                  class="list-group-item {{
                    isInActiveGroupItems(child) ? 'active' : ''
                  }}"
                  (click)="toggleActiveInGroup(child)"
                >
                  {{ child.value }}
                </li>
              </ul>
            </div>
          </div>
        </div>
        <div
          class="col-2 d-flex flex-column justify-content-center list-arrows"
        >
          <button
            type="button"
            class="btn btn-outline-primary my-3 move-right"
            (click)="moveToTheRight()"
          >
            Move Right
          </button>
          <button
            type="button"
            class="btn btn-outline-primary my-3 move-left"
            (click)="moveToTheLeft()"
          >
            Move Left
          </button>
        </div>
        <div class="col">
          <div class="card shadow-sm border-0 swap-list list-right">
            <div class="card-header border-bottom-0 rounded-top">
              <div class="row">
                <div class="col d-flex align-items-center">
                  <input
                    type="text"
                    class="form-control"
                    placeholder="Search"
                  />
                </div>
              </div>
            </div>
            <div class="card-body overflow-auto py-0">
              <ul
                class="list-group list-group-flush"
                *ngFor="let child of agentNotinView"
                name="agentNotInGroup"
              >
                <li
                  class="list-group-item {{
                    isInActiveNotGroupItems(child) ? 'active' : ''
                  }}"
                  (click)="toggleActiveNotInGroup(child)"
                >
                  <input type="text" [(ngModel)]="child.value" />
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

TS:

public moveToTheRight(): void {
    this.move('agentInView', 'agentNotinView');
  }

  public moveToTheLeft(): void {
    this.move('agentNotinView', 'agentInView');
  }

  // moving function
  public move(from: string, to: string): void {
    this[from].filter((item: any, i: number) => {
      if (this.isInActiveGroupItems(item)) {
        this[to].push(item);
        this[from].push(item);
        return false;
      } else {
        return true;
      }
    });

    // if needed
    // sort if needed
    this[to].sort((a, b) => (a.id > b.id ? 1 : -1));

    // clean active items after action
    this.activeItemsGroupView.length = 0;
    //this.activeItemsNotInGroup.length = 0;
  }

  public toggleActiveInGroup(eventItem: any): void {
    if (this.activeItemsGroupView.find((item) => item === eventItem)) {
      this.activeItemsGroupView = this.activeItemsGroupView.filter(
        (item) => item !== eventItem
      );
    } else {
      this.activeItemsGroupView.push(eventItem);
    }
  }
  public toggleActiveNotInGroup(eventItem: any): void {
    if (this.activeItemsNotInGroup.find((item) => item === eventItem)) {
      this.activeItemsNotInGroup = this.activeItemsNotInGroup.filter(
        (item) => item !== eventItem
      );
    } else {
      this.activeItemsNotInGroup.push(eventItem);
    }
  }

  public isInActiveGroupItems(eventItem: any): boolean {
    return !!this.activeItemsGroupView.find((item) => item === eventItem);
  }
  public isInActiveNotGroupItems(eventItem: any): boolean {
    return !!this.activeItemsNotInGroup.find((item) => item === eventItem);
  }

DEMO

Advertisement

Answer

You are pushing the same instance into both arrays. You should create a new object at some point, so that you don’t edit the same object reference and propagate your changes in places you don’t want them. I suggest to make a new reference by using destructuring inside your move method:

  // moving function
  public move(from: string, to: string): void {
    this[from].filter((item: any, i: number) => {
      if (this.isInActiveGroupItems(item)) {
        this[to].push({...item});
        this[from].push(item);
        return false;
      } else {
        return true;
      }
    });

    // if needed
    // sort if needed
    this[to].sort((a, b) => (a.id > b.id ? 1 : -1));

    // clean active items after action
    this.activeItemsGroupView.length = 0;
    //this.activeItemsNotInGroup.length = 0;
  }
Advertisement