0

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?

2 Answers 2

3

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

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

Comments

2

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

2 Comments

It's a wonderful solution, definitely works, but does not fit my project that I am migrating. Thank you though. As for why it does not work, my data model that I later must post would require to revert the object model.
@dovexz12323 thank you, all the best :) no problems :)

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.