15

I have problem with binary, even if add brackets to it.

I'm using primeNG library.

In HTML file I wrote this code:

<div class="products-page">
    <div class="p-grid">
      <div class="p-col-3" *ngIf="!isCategoryPage">
        <h4>Categories</h4>
        <div class="p-field-checkbox" *ngFor="let category of categories">
          <p-checkbox
            [(ngModel)]="category.checked"
            binary="true"
            [inputId]="category.id"
            (onChange)="categoryFilter()"
          ></p-checkbox>
          <label for="{{ category.id }}">{{ category.name }}</label>
        </div>
      </div>
      <div [ngClass]="{ 'p-col-9': !isCategoryPage, 'p-col-12': isCategoryPage }">
        <div class="p-grid" *ngIf="products">
          <div
            [ngClass]="{ 'p-col-4': !isCategoryPage, 'p-col-3': isCategoryPage }"
            *ngFor="let product of products"
          >
            <products-product-item [product]="product"></products-product-item>
          </div>
        </div>
      </div>
    </div>
  </div>

,,,,

In ts file:

import { Component, OnInit } from '@angular/core';
import { Product, Category } from '@bluebits/products';
import { ProductsService } from '../../services/products.service';
import { CategoriesService } from '../../services/categories.service';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'products-list',
  templateUrl: './products-list.component.html'
})
export class ProductsListComponent implements OnInit {

  products: Product[] = [];
  categories: Category[] = [];
  isCategoryPage: boolean;

  constructor(
    private prodService: ProductsService,
    private catService: CategoriesService,
    private route: ActivatedRoute
    ) { }

  ngOnInit(): void {
    this.route.params.subscribe((params) => {
      params.categoryid ? this._getProducts([params.categoryid]) : this._getProducts();
      params.categoryid ? (this.isCategoryPage = true) : (this.isCategoryPage = false);
    });
    this._getCategories();
  }

  private _getProducts(categoriesFilter?: string[]) {
    this.prodService.getProducts(categoriesFilter).subscribe((resProducts) => {
      this.products = resProducts;
    });
  }

  private _getCategories() {
    this.catService.getCategories().subscribe(
      (resCats) => {
        this.categories = resCats;
      }
    )
  }

  categoryFilter() {
    const selectedCategories = this.categories
      .filter((category) => category.checked)
      .map((category) => category.id);

    this._getProducts(selectedCategories);
  }
}

In module file:

I Import this module

import { CheckboxModule } from 'primeng/checkbox';

I got this error:

error TS2322: Type 'string' is not assignable to type 'boolean'.

binary="true"

How can I fix it?

JGallardo
  • 11,074
  • 10
  • 82
  • 96
Salman
  • 209
  • 1
  • 3
  • 7
  • 5
    [enter image description here](https://imgur.com/TmPQIOz) – David Sep 01 '21 at 13:32
  • 1
    Avoid posting code screenshots, use `codeblocks` instead so people can copy and paste your code, allowing to reproduce your problems more easily. – Allan Juan Sep 01 '21 at 13:38

4 Answers4

31

When you do binary="true", you're assigning a string to a property that expects a boolean. To pass the true boolean value rather than the "true" string you'll have to use the brackets syntax:

<p-checkbox [binary]="true" [(ngModel)]="checked"></p-checkbox>
Allan Juan
  • 2,048
  • 1
  • 18
  • 42
4

The Angular CDK has a useful concept of declaring your @Input()s as BooleanInput instead of boolean. This allows myProp="true" to work in addition to [myProp]=true.

The coerceBooleanProperty function ensures that the input value is a boolean.

Craig Shearer
  • 14,222
  • 19
  • 64
  • 95
2

Try to add [value]="true" attribute:

<p-checkbox [(ngModel)]="category.checked" [binary]="true" [value]="true"></p-checkbox>
0

Just to clarify and add some references:

The binary attribute is a boolean property of the p-checkbox. Your angular template is attempting to set (bind) it to true (it might not seem evident at first glance that the attribute assignment binds a property, but as the docs suggest: "In most cases, the target name is the name of a property, even when it appears to be the name of an attribute.").

The same doc proceeds to state:

The brackets, [], cause Angular to evaluate the right-hand side of the assignment as a dynamic expression. Without the brackets, Angular treats the right-hand side as a string literal and sets the property to that static value.

I.E., w/o the brackets, 'binary' is assigned the 'true' string literal, which is then flagged as an assignment error by typescript. [binary]='true' triggers an evaluation of 'true' to the boolean value.

BTW, you might conclude that you can workaround the issue by using interpolation (binary="{{true}}"). Indeed the angular docs support this notion, stating that "Often interpolation and property binding can achieve the same results.". It does however qualify that by noting that "when setting an element property to a non-string data value, you must use property binding".

pointyhat
  • 568
  • 5
  • 16