Home > Back-end >  Add or remove values to lists accordingly with [checked] property does not work as expected
Add or remove values to lists accordingly with [checked] property does not work as expected

Time:08-26

I have created a stackBlitz to showcase the functionality.

https://stackblitz.com/edit/angular-ivy-nbmvfn?file=src/app/app.component.ts

I have two different lists, with different object structure, I need to check the checkboxes accordingly to what is returned from the initial list, update the list with appending it with the value, and later on in my application save it (not in stackblitz).

Currently it's misbehaving, I have created a method to check whether the checkbox should be pre-checked or not while onInit, but when adding or removing (checking the checkboxes) the objects from the list, it's either not removed, or a different checkbox index is unchecked. My whole solution as of this point is in stackBlitz.

What could be the issue and how do I fix such behaviour?

CodePudding user response:

You cannot compare a string, value to an object, the contents of obj. You have to dig into the object and compare the strings directly. Updated onChange method:

onChange($event, object) {
    const value = $event.target.value;
    const isChecked = $event.target.checked;
    const item = {
      uri: value,
    };

    if (isChecked === true) {
      this.userEndpoints.push(item);
      console.log(item);
    } else if (isChecked === false) {
      let index = -1
      this.userEndpoints.forEach((endpoint, idx) => {
        if (endpoint.uri === value) {
          index = idx
        }
        if (index > -1) {
          return
        }
      })
      this.userEndpoints.splice(index, 1);
      console.log(this.userEndpoints);
    } else console.log('Failed');
  }

forked stackblitz

CodePudding user response:

Don't waste your time tracking two lists, instead merge those two into a single list, please find below an example of the implementation.

ts

import { Component, OnInit } from '@angular/core';
import { AllEndpoints } from './all-endpoints';
import { UserEndpoints } from './user-endpoints';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  endpointList: AllEndpoints[];
  userEndpoints: UserEndpoints[];

  ngOnInit(): void {
    this.userEndpoints = [{ uri: '/home' }, { uri: '/information' }];

    this.endpointList = [
      { endpoint: '/home', method: 'GET' },
      { endpoint: '/login', method: 'GET' },
      { endpoint: '/information', method: 'GET' },
    ];
    this.endpointList.forEach((item) => {
      const found =
        this.userEndpoints.find((x) => x.uri === item.endpoint) || null;
      item.checked = !!found;
    });
  }

  onChange($event, object) {
    const value = $event.target.value;
    const isChecked = $event.target.checked;
    const obj = eval(`this.${object}`);
    const item = {
      uri: value,
    };

    if (isChecked === true) {
      obj.push(item);
    } else if (isChecked === false) {
      obj.splice(obj.indexOf(value), 1);
    } else console.log('Failed');
    console.log(obj);
    return obj;
  }

  isChecked(endpoint: string): boolean {
    return !!this.userEndpoints.find((x) => x.uri === endpoint);
  }

  save() {
    alert(
      `items to be saved ${JSON.stringify(
        this.endpointList.filter((x) => x.checked)
      )}`
    );
  }
}

html

<form (submit)="save()">
  <label for="enabledEndpoints">Enabled Endpoints</label>
  <div *ngFor="let item of endpointList">
    <input
      type="checkbox"
      [id]="item.endpoint"
      [value]="item.endpoint"
      name="enabledEndpoints"
      [checked]="item.checked"
      (change)="item.checked = !item.checked"
    />
    <label [for]="item.endpoint"> {{ item.endpoint }}</label>
  </div>
  <span>{{ endpointList | json }}</span>
  <button type="submit">save</button>
</form>

forked stackblitz

  • Related