#checkbox event

107 messages · Page 1 of 1 (latest)

neat cedar
#

Hello. Is there a way to toggle checkbox but not fire the event?
My checkbox fires event on toggle and it calls api but it shouldn't.
I have a button "Apply" which should read checkbox value and then when clicked call API.

    <div class="custom-control custom-checkbox mt-3 mb-2 pl-4">
      <input type="checkbox" class="custom-control-input" id="customCheck1" formControlName="isOverdue">
      <label class="custom-control-label" for="customCheck1">Overdue</label>
    </div>

smoky junco
#

How are u triggering the api call?

#

Using valueChanges ?

neat cedar
#

Just jusing. This should emit to service which then should call API. But checkbox calls API first without apply method

  public apply(): void {
    console.error("Apply!");
    this.change.emit();
    this.open = false;
  }

smoky junco
#

That doesnt trigger An api call

#

What triggers it ?

neat cedar
#

That method emits to service which uses FormGroup data

 <button class="btn btn-secondary" (click)="apply()"Apply filters</button>

// And in service:
 private createQueryModel(): QueryInputFilters {
    const formData = this.filterForm.getRawValue();
    const filters: QueryInputFilters = {};
    console.error(formData.isOverdue);
    filters.isOverdue = formData.isOverdue ? true : undefined;

    Object.keys(filters).forEach(key => filters[key] === undefined ? delete filters[key] : {});

    console.log('filters', filters)
    return filters;
  }
#
  private createQueryInput(): QueryInput {
    const query = this.createQueryModel() as QueryInput;
    const metaData = this.metadataForm.getRawValue();
    query.limit = metaData.limit ? metaData.limit : 20;
    query.offset = metaData.offset ? metaData.offset : 0;

    return query;
  }
#

All other filters work as they should

#

IF i make this checkbox into Radio, it works as intended

smoky junco
#

So you are having issues with an API call that gets called at the wrong time

#

But you arent showing the code that triggers the API call.

#

How do u expect people to understand what is happening in your code?

neat cedar
#

Not sure if this is better?

filter.html
<div class="custom-control custom-checkbox mt-3 mb-2 pl-4">
      <input type="checkbox" class="custom-control-input" id="customCheck1" formControlName="isOverdue">
      <label class="custom-control-label" for="customCheck1">Overdue</label>
    </div>

<button class="btn btn-secondary" (click)="apply()"Apply filters</button>
filter.html
//
list.component.ts
  public filter(): void {
    // this gets called on checkbox toggle
    this.reportListService.query();
  }
list.component.ts
//
filter.component.ts
  @Output()
  public readonly change = new EventEmitter<void>();

  public apply(): void {
    this.change.emit();
    this.open = false;
  }
filter.compnent.ts
//
service.ts
  public readonly filterForm = new FormGroup({
    isOverdue: new FormControl(),
  });

  public query(): void {
    this.loadingSource.next(true);

    const query = this.createQueryInput();
// API CALL
    this.orderReportRes.query(query).then(res => {
      this.setList(res);
    }).finally(() => {
      this.loadingSource.next(false);
    });
  }

  private createQueryInput(): QueryInput {
    const query = this.createQueryModel() as QueryInput;
    const metaData = this.metadataForm.getRawValue();
    query.limit = metaData.limit ? metaData.limit : 20;
    query.offset = metaData.offset ? metaData.offset : 0;

    return query;
  }

 private createQueryModel(): QueryInputFilters {
    const formData = this.filterForm.getRawValue();
    const filters: QueryInputFilters = {};
    console.error(formData.isOverdue);
    filters.isOverdue = formData.isOverdue ? true : undefined;

    Object.keys(filters).forEach(key => filters[key] === undefined ? delete filters[key] : {});

    console.log('filters', filters)
    return filters;
  }

  private setList(res: QueryOutput) {
    this.listSource.next(res.orders);
  }
smoky junco
#
  public filter(): void {
    // this gets called on checkbox toggle
    this.reportListService.query();
  }
#

What calls filter ?

neat cedar
#

oh.. table list view component

.list.component.html
<app-report-filters (change)="filter()"></app-report-filters>

app-report-filters = filter.component.ts
smoky junco
#

So what calls change? ...

#

Ah apply does ?

neat cedar
#

yes

smoky junco
#

Please share the filter component.

neat cedar
smoky junco
#

So you are saying that, if you comment out this.change.emit() it still triggers the API call when u toggle the checkbox ?

neat cedar
#

Yes

smoky junco
#

So something else is triggering the API call. But its hard to tell with the code you are sharing.

hexed kayak
smoky junco
#

Do u have any subscriptions on the checkbox form control?

neat cedar
#

No subscriptions. 1 sec with the html

#

I removed other filters

<!-- Sidebar start-->
<aside class="filter" [class.show]="open">

  <nav [formGroup]="filterForm">
    <div class="d-flex justify-content-between">
      <h4>Filtreeri</h4>
      <button class="btn btn-link btn-sm p-0" (click)="clear()">Clear filters</button>
    </div>
   
    <div class="custom-control custom-checkbox mt-3 mb-2 pl-4">
      <input type="checkbox" class="custom-control-input" id="customCheck1" formControlName="isOverdue">
      <label class="custom-control-label" for="customCheck1">Overdue</label>
    </div>

// This radiobutton doesn't call api. But I must use checkbox
    <div class="custom-control custom-checkbox mt-3 mb-2 pl-4">
      <div btnRadioGroup class="dateFilter-btn-group btn-group d-flex" formControlName="isOverdue">
      <label uncheckable
             class="btn btn-outline-primary btn-sm"
             btnRadio="isOverdue"
             tabindex="0"
             role="button">
        Overdue
      </label>
    </div>
    </div>
//
   
    <div class="filter-buttons">
      <button class="btn btn-secondary" (click)="apply()">Apply filters</button>
      <button class="btn btn-light" (click)="close()">Close</button>
    </div>
  </nav>
</aside>
smoky junco
#

But thats a div, not a radio button.

neat cedar
#

Even if I change it to <input radio> it doesn't trigger

smoky junco
#

Something has to trigger the API call apart from apply.

#

But I havent seen any of that code, so it's hard to tell.

neat cedar
#

It must be in the service then I guess

smoky junco
#

Can u share the service ?

neat cedar
hexed kayak
smoky junco
#
private listenToMetadata(): void {
    this.metadataForm.valueChanges.subscribe(() => {
      if (this.metadataResetLock) return;

      this.query();
    });
  }
#

Whats this ?

neat cedar
#

I'm not sure. That is not written by me

smoky junco
#

Add a console log

#

and see if it is the thing that triggers the call.

#

Like it seems to be configured to do a call whenever the metadata changes, or gets reset.

#

So whenever u call resetMetadata or setMetadata.

neat cedar
#

It didn't get there

smoky junco
hexed kayak
#

@neat cedar is the APi call triggered on each checkbox interaction?

neat cedar
#

Yes, on eaech interaction

smoky junco
#

Is something else calling query on the service?

#

It reads like a subscribe on valueChanges tho.

hexed kayak
#

Check in your project is there is some sort of filterForm.valueChanges.

neat cedar
#

Only one is in this service layer

smoky junco
#

Add a breakpoint in the query method and see what calls it.

#

Or try adding console.trace() in the query method of the service.

neat cedar
#

This is what I got from checkbox toggle

smoky junco
#

So u have a filter listener in report-list on line 48.

#

or in the html on 348

#

Can u show the html and component ts ?

neat cedar
#

list.component.html is the table view. Yes, 1 second

smoky junco
#

Its report-list

neat cedar
#

It has lots of code. Maybe I show the place where its called?

smoky junco
#

Show the relevant parts.

neat cedar
#

This is at the end of the html

<ng-template #loadingTemplate>
  <div class="loading-spinner"></div>
</ng-template>

<app-report-filters (change)="filter()"></app-report-filters>
<div class="filters-background"></div>
smoky junco
#

Ah so its that code

hexed kayak
#

@smoky junco i wonder if that's about using 'change' as a name for EventEmitter, which might come in conflict with native html listerner

smoky junco
#

Maybe, but they just said apply isnt called in the filter component, so it shouldnt trigger change.

#

so what u say could be the case, But I dont see what a change event on a custom element means.

#

Sounds random for a checkbox to buble a change event to a custom component

hexed kayak
smoky junco
#

Yeah no worries, it's a fair thing to try.

#

So @neat cedar there is only one thing calling emit on the filter, right ?

#

Its apply ?

neat cedar
#

Yes

smoky junco
#

But u said apply isnt called?

neat cedar
#

Yes, I have a button for Apply

#

RIght now I have "this.change.emit" commented out

smoky junco
#

Try adding console.trace() in the apply method.

neat cedar
#

Okay

smoky junco
#

And it still calls change ?

neat cedar
#

yes

smoky junco
#

Try renaming change to filterChange.

neat cedar
#

This is when i clicked apply

smoky junco
#

Would sound random if it fixes it, but worth trying

neat cedar
#

Still calls api

hexed kayak
# smoky junco Sounds random for a checkbox to buble a change event to a custom component

A angular-cli project based on @angular/animations, @angular/compiler, @angular/core, @angular/common, @angular/platform-browser-dynamic, @angular/forms, @angular/platform-browser, rxjs, tslib, zone.js and @angular/router.

#

by using change name

smoky junco
#

But it doesnt happen with input texts and radio buttons ?

#

I tried it, it does.

#

The OP said it only was an issue with the checkbox, and not any other filter.

#

Good catch tho @hexed kayak .

neat cedar
#

What is happening there?

smoky junco
#

Event bubbling, I guess.

#

change is triggered on a child of the filter component

#

so unless u prevent bubbling, it calls change on the parents, including the filter.

#

I would have thought a custom component wouldnt have a change event 🤔

#

Nvm, its monday.

#

It does have a change event (the output), and it triggers it

#

So probably is expected behavior. But I am not sure I would expect that myself 😂

#

But renaming it to filterChange should solve this bubbling.

hexed kayak
neat cedar
#

Oh wow it did!!!

#

Next time I'm coding something like this again I should use better naming?

smoky junco
#

Try and avoid build in names

#

like change, input, click, ...

neat cedar
#

Okay, I'll keep that in mind and write it down

#

Thank you both so much