0

I’m developing a standalone component in Angular 20 and I’m getting this error:

ERROR TypeError: ctx.widgetSize is not a function
    at SanctionWidgetComponent_Template (sanction-widget.component.html:1:1)

Context

Here is my SanctionWidgetComponent:

import { Component, input, SimpleChanges } from '@angular/core';
import { SanctionData } from './model/sanction-data';
import { Size } from '../../../../features/dashboard/models/modal-widget.model';
import { TimeSlot } from '../../../../shared/shared.model';
import { FormatNumberPipe } from '../../../../shared/pipes/format-number.pipe';

@Component({
  selector: 'app-sanction-widget',
  templateUrl: './sanction-widget.component.html',
  styleUrls: ['./sanction-widget.component.scss'],
  standalone: true,
  imports: [FormatNumberPipe]
})
export class SanctionWidgetComponent {
    data = input<SanctionData>({
    date: '19/09/2024',
    year: '2025',
    amount: 200000,
    totalAmount: 500000,
    trendPercentage: 4,
    trendAmount: 50000
  });
  widgetSize = input<Size>(Size.XS);
  selectedLocation = input<string>('');
  timeslot = input<TimeSlot>();

  validData = false;


  protected readonly Size = Size;
}

HTML Template

I removed the CSS classes and replaced mds-text and mds-icon with standard HTML tags. The @if structure remains unchanged:

@if (widgetSize() === Size.XS) {
  <div>
    <span>Collected {{ data()?.year }}</span>
    <div>{{ data()?.amount ?? 0 | formatNumber }} €</div>
    <span>Total to collect: {{ data()?.totalAmount ?? 0 | formatNumber }}€</span>
  </div>
}

@if (widgetSize() === Size.S) {
  <div>
    <div>
      <div>
        <span>Collected {{ data()?.year }}</span>
        <div>{{ data()?.amount ?? 0 | formatNumber }} €</div>
      </div>
      <span>Total to collect: {{ data()?.totalAmount ?? 0 | formatNumber }}€</span>
    </div>

    <div>
      <span>[icon]</span>
      <span>{{ data()?.trendAmount ?? 0 | formatNumber }}€</span>
    </div>

    <div>
      <span>[icon]</span>
      <span>{{ data()?.trendPercentage ?? 0 | formatNumber }}€</span>
    </div>
  </div>
}

This is the parent component, where I dynamically set all inputs:

 loadComponent(): void {
    const viewContainerRef = this.appWidgetHost.viewContainerRef;
    viewContainerRef.clear();

    // Ottieni il tipo di componente dal servizio
    const componentType = this.widgetFactory.getComponent(this.widgetType);

    if (componentType) {
      const componentRef = viewContainerRef.createComponent(componentType);
      this.currentComponentRef = componentRef;

      // Passa i dati se esistono
      this.widgetDataService
        .getWidgetConfig(this.widgetType)
        .pipe()
        .subscribe({
          next: widgetConfig => {
            if (widgetConfig && widgetConfig.data) {
              componentRef.setInput('data', widgetConfig.data);
              componentRef.setInput('widgetSize', this.widgetSize);
              componentRef.setInput('timeslot', this.getWidgetInfoByType(this.widgetType).timeSlot);
              componentRef.setInput('selectedLocation', widgetConfig.selectedLocation);

              this.cdr.markForCheck();
            }
          }
        });
    } else {
      console.error(`Componente per ${this.widgetType} non trovato.`);
    }
  }

Problem

Even though widgetSize is correctly set in the parent component, Angular throws:

ctx.widgetSize is not a function

I read that this can happen when trying to call a property as a function, but I’m using @if with widgetSize() according to the template syntax. If I remove widgetSize attribute, the problem involved also other inputs, like "data" object.


Questions

  1. What is the correct way in Angular 20 to use @if with a property like widgetSize?
  2. Should I call widgetSize() or just use widgetSize?
  3. How can I make the template work without causing this error?
3
  • How's widgetSize defined on your parent component, and how do you create the componentRef? Commented Sep 25 at 11:42
  • Also, it seems like you are importing Input and not input from @angular/core. So what input are you actually using in your component? Commented Sep 25 at 11:51
  • @PoulKruijt I edited the post. The import was wrong and I posted all the parent function Commented Sep 25 at 12:18

0

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.