Angular 17 isn't notifying child component of signal changes

In the statistics module, I have a signal that specifies the type of charts to display and this signal is updated through a radio button group. The signal:

typeSignal = signal<string>('OIA')

The radio buttons for setting the :

<div class="btn-group w-auto" role="group">
     @for (type of types; track $index) {
            <input type="radio" class="btn-check" name="btnradio" [id]="type" autocomplete="off"
                [checked]="type==typeSignal()">
            <label class="btn btn-primary" for="btnradio1" (click)="typeSignal.set(type)">{{type}}</label>
     }
</div>

Additionally, there is another computed signal that generates data for the charts based on the type signal. Here's the charts signal:

  charts = computed(() => {
    const chartsArr:ChartData[] = []
   if (this.typeSignal() == "OIA") {

      chartsArr.push(this.createBarChart("Status of Incident", ['Closed', 'Ongoing'], "status", "Advisories", true))
      chartsArr.push(this.createBarChart("Severity of Incident", ['Severity 0', 'Severity 1', 'Severity 2', 'Severity 3', 'Severity 4'], "impacts", "Advisories", false))
      chartsArr.push(this.createDonutChart("Communication type", ['Incident', 'Change'], 300))

    } else if (this.typeSignal() == "Portail de l'information") {

      chartsArr.push(this.createBarChart("Status of Incident", ['Scheduled', 'Archived', 'Ongoing'], "status", "Advisories", true))
      chartsArr.push(this.createBarChart("Impact of Incident", ['Major', 'Minor', 'Grave'], "impacts", "Advisories", false))
      chartsArr.push(this.createDonutChart("Communication type", ['Incident', 'Change'], 300))

    } else if (this.typeSignal() == "Bulletin Board") {
      chartsArr.push(this.createBarChart("Status of Change", ['Closed', 'Ongoing', 'Scheduled'], "status", "Advisories", true))
      chartsArr.push(this.createBarChart("Outage of Incident", ['Complete Outage', 'Partial Outage', 'Info'], "impacts", "Advisories", false))
      chartsArr.push(this.createDonutChart("Communication type", ['Info', 'Incident', 'Change'], 300))
    }
    console.log(chartsArr);
    return structuredClone(chartsArr)
  })

In the template, I'm reading this charts signal as follows:

@if (["OIA","Portail de l'information","Bulletin Board"].includes(typeSignal())) {
<div class="row row-cols-2 g-5 mx-1">
    @for (chart of charts(); track $index) {
    @if (chart.type == "bar") {
    <app-bar-chart [title]="chart.title" [axissLabels]="chart.labels" [values]="chart.values"
        [valuesType]="chart.valuesType!" [isHorizontal]="chart.isHorizontal!"></app-bar-chart>
    }@else if (chart.type=="donut") {
    <app-donut-chart [title]="chart.title" [values]="chart.values" [labels]="chart.labels"
        [minWidth]="chart.minWidth!"></app-donut-chart>
    }
    }

</div>
}

The issue here is that the charts signal does not update the for loop even though the console.log(chartsArr); within it gets logged whenever I toggle the radio buttons.

Answer №1

Upon investigation, it became apparent that the issue did not stem from the signal itself.

The root of the problem lay in the child components BarChartComponent and DonutChartComponent.

These components were failing to detect update changes, prompting the addition of OnChanges.

Below is the revised code for DonutChartComponent:

export type ChartOptions = {
  series: ApexNonAxisChartSeries;
  chart: ApexChart;
  responsive: ApexResponsive[];
  labels: string[];
  title: ApexTitleSubtitle;
};

@Component({
  selector: 'app-donut-chart',
  standalone: true,
  imports: [NgApexchartsModule],
  templateUrl: './donut-chart.component.html',
  styleUrl: './donut-chart.component.scss'
})
export class DonutChartComponent implements OnInit, OnChanges {
  @ViewChild("chart") chart!: ChartComponent;
  chartOptions!: Partial<ChartOptions>;

  @Input() values: number[] = []
  @Input() labels: string[] = []

  @Input() title!: string
  @Input() minWidth!: number


  ngOnInit(): void {
    this.createChart()
  }
  ngOnChanges(changes: SimpleChanges) {
    if (Object.keys(changes).length > 0) {
      if (changes['values']?.currentValue) {
        this.values = changes['values']?.currentValue
      }
      if (changes['labels']?.currentValue) {
        this.labels = changes['labels']?.currentValue
      }
      if (changes['title']?.currentValue) {
        this.title = changes['title']?.currentValue
      }
      if (changes['minWidth']?.currentValue) {
        this.minWidth = changes['minWidth']?.currentValue
      }
      this.createChart()
    }
  }

  createChart() {
    this.chartOptions = {
      title: {
        text: this.title
      },
      series: this.values,
      chart: {
        type: "donut",
      },
      labels: this.labels,
      responsive: [
        {
          breakpoint: this.minWidth,
          options: {
            chart: {
              width: this.minWidth,
            },
            legend: {
              position: "bottom",
            },
          },
        },
      ],
    };
  }

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to adjust the properties within a type that are nested

I'm looking to modify a specific type in my code while retaining the other properties. Can anyone help? type Foo = { a: { b: { c: string[] ...rest } ...rest } ...rest } Is there a way to change the type of a.b.c without ...

Detecting if a string is in sentence or title case with a typeguard

When setting the sameSite property of a cookie, it must be either Strict, Lax, or None. However, the package I'm using uses lowercase values for this attribute. Therefore, I need to adjust the first letter of the string: let sentenceCaseSameSite: &quo ...

What is the best way to incorporate or reference an existing AngularJS project in a new project?

https://i.stack.imgur.com/2dkC0.png The image suggests that Angular app1 serves as a shared module for both app2 and app3. Is there a way to inject app2 and app3 into the common module? If direct injection is not possible, does anyone have suggestions on ...

Error: Property 'xxx' is not a valid attribute for this type

Hey there! I recently converted my React Native JavaScript project into TypeScript and everything seems to be working fine. However, I'm encountering some warnings that I could use some help with. Specifically, I need assistance on how to properly pas ...

Send inputs to an Angular page discretely without them being visible in the URL

We are in the process of developing a standalone Angular web page specifically for password maintenance that will be accessed by all our external applications with login capabilities. Our goal is to streamline the password change process by pre-populating ...

What are some best practices for managing object-level variables in TypeScript and Vue.js?

Uncertain about the optimal approach, I am looking to create a component and leverage some object level variables. Consider the example below: import Vue from "vue" import * as paper from "paper" export default Vue.extend({ template: ` <d ...

Whenever a file is chosen, I aim to generate the video HTML dynamically and display the video with play functionalities using Angular 2 and TypeScript

I am attempting to allow users to select a video file and display it so they can play it after choosing the file. Below is my HTML code: <br> <input type="file" (change)="fileChangeEvent($event)" placeholder="upload file..." class=" ...

The NGXS state does not get updated when a lazy loaded component is used

Recently, I started experimenting with the new lazy loaded components in Angular 9. I have a stateful component using NGXS with its state being lazy loaded in a module close to the component. However, after the component renders, the store does not update ...

Troubleshooting the issue with mocking the useTranslation function for i18n in JEST

Currently, I am facing an issue with my react component that utilizes translations from i18next. Despite trying to create tests for it using JEST, nothing seems to be getting translated. I attempted to mock the useTranslation function as shown below: cons ...

React Scheduler by Bryntum

After successfully discovering some functions related to various actions, I find myself still in need of additional functions: Currently, I am utilizing these functions by passing them directly as props to the Scheduler React Component: - onBeforeEventSa ...

Attempting to test a Jasmine directive in Angular results in failure

After creating a simple directive that throws an error when the input is invalid, I encountered an issue with my testing. When attempting to test for the thrown error using expect().toThrow(), it succeeded as expected. However, the same result occurred w ...

Learn the steps to assign a Base64 URL to an image source

I am currently facing an issue with an image that is being used with angular-cli: <img src="" style="width: 120px; padding-top: 10px" alt="" id="dishPhoto"> The image has a Base64 url named imgUrl. My intention is to set the image source using the ...

Please eliminate the notification stating "The baseHref option is deprecated, instead use the baseHref option directly in the browser builder."

After updating my project to Angular version 11, I encountered an error when trying to run it: "Option baseHref is deprecated, use baseHref option in the browser builder itself". I attempted to add baseHref: "/certs/" in angular.json, but the error persis ...

Module 'next-intl/client' cannot be located

When I run npm test, I encounter the following error: 'next-intl/client' module not found jest.mock( | ^ 22 | 'next-intl/client', 23 | (): Record<string, unknown> => ({ 24 | usePathname: ...

I am attempting to make the fade in and out effect function properly in my slideshow

I've encountered an issue where the fading effect only occurs when the page initially loads and solely on the first image. Subsequently, the fading effect does not work on any other images displayed. This is the CSS code I have implemented by adding ...

The cancel function in lodash's debounce feature does not successfully halt the execution of the

In my angular application, I have implemented http calls on each modelChange event with the help of lodash's _.debounce(). However, I'm facing an issue where I am unable to cancel these calls after the initial successful execution of debounce. ...

Reveal the class to the global scope in TypeScript

ClassExample.ts: export class ClassExample{ constructor(){} } index.html: <script src="ClassExample.js"></<script> // compiled to es5 <script> var classExample = new ClassExample(); //ClassExample is not defined < ...

Issue with the proper functionality of the this.formGroup.updateValueAndValidity() method in Angular 6

Currently, I am facing an issue where I need to add or remove validators in a formGroup's controls based on certain conditions. When I try to update the validators using `formGroup.updateValueAndValidity()` for the entire form, it does not seem to wor ...

Add a service to populate the values in the environment.ts configuration file

My angular service is called clientAppSettings.service.ts. It retrieves configuration values from a json file on the backend named appsettings.json. I need to inject this angular service in order to populate the values in the environment.ts file. Specific ...

Custom-designed foundation UI element with a parameter triggers TypeScript issue

When running this tsx code: import React from "react"; import BaseButton from "@mui/base/Button"; import styled from "@emotion/styled"; export const enum BUTTON_TYPE { MAIN = "main", LINK = "link", } ...