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

Viewed 20289

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?

5 Answers

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>

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

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

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.

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".

I solved this by modifying the angularCompilerOptions inside the tsconfig.json file.

Remove the strictTemplates property if it is set.

Related