Am I utilizing Angular's signals correctly? And what is the purpose of still requiring ChangeDetectorRef.detectChanges()?

I have been experimenting with signals and I am questioning whether the current use case would be more beneficial without using Signals and instead just having a "normal" class member swiper?: Swiper:

@Component({
  selector: '[app-test]',
  standalone: true,
  imports: [CommonModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TestComponent implements AfterViewInit {
  swiper = signal<Swiper|undefined>(undefined);

  constructor(
    private readonly cd: ChangeDetectorRef,
    private readonly elementRef: ElementRef,
  ) { }

  ngAfterViewInit(): void {
    const swiper: unknown = this.elementRef.nativeElement.querySelector('swiper-container')?.swiper;

    if (swiper instanceof Swiper) {
      this.swiper.set(swiper);
      this.cd.detectChanges();
    }
  }

  slideTo(direction: 'prev'|'next'): void {
    const swiper = this.swiper();
    if (!swiper) return;
    direction === 'prev' ? swiper.slidePrev() : swiper.slideNext();
  }
}

And within the template:

<fieldset *ngIf="swiper() as swiper">
  <button
    type="button"
    [attr.disabled]="swiper.activeIndex === 0 ? true : null"
    (click)="slideTo('prev')"
  >Prev</button>

  <button
    class="slider-navigation slider-navigation--next"
    type="button"
    [attr.disabled]="swiper.activeIndex === swiper.slides.length - 1 ? true : null"
    (click)="slideTo('next')"
  >Next</button>
</fieldset>

I acknowledge the need for this.cd.detectChanges(); since ngAfterViewInit is executed after Angular's change detection. But I find myself wondering if Signals truly make a difference here, as it seems to essentially replicate not using Signals at all. What advantages do Signals offer in this scenario? Am I implementing them correctly?

Answer №1

Upon conducting a thorough investigation as a team, we discovered that the issue in both versions of the code stems from the Change Detection cycle concluding after setting a signal.

This is why markForCheck() is ineffective (as the signal already marks the views), while detectChanges() proves successful - requiring an additional CD cycle to inspect all marked views.

Validated by Alex Rickabaugh.


Prior response:

Your code can be accessed on StackBlitz here: https://stackblitz.com/edit/stackblitz-starters-1tnwzf?file=src%2Fmain.ts

It functions without requiring a cd.detectChanges() invocation. It simply outputs a well-known error to the console in development mode ;)

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

Angular's two-way binding feature does not seem to be updating the value for date

In my Angular - Dotnetcore 2.0 form, users are required to update their demographic information including their birth date. Initially, I was using the following code snippet to display the birthdate: <input id="dateOfBirth" type="date" class="form-cont ...

I encountered a mistake: error TS2554 - I was expecting 1 argument, but none was given. Additionally, I received another error stating that an argument for 'params' was not provided

customer-list.component.ts To load customers, the onLoadCustomers() function in this component calls the getCustomers() method from the customer service. customer.servise.ts The getCustomers() method in the customer service makes a POST request to the A ...

Troubleshooting problem with @Input number in Angular 2

Here is the component in question: <component value="3"></component> This is the code for the component: private _value:number; get value(): number { return this._value; } @Input() set value(value: number) { console.log(v ...

Invoke an Angular function from a dynamically inserted hyperlink

Recently, I've been dynamically adding HTML to my page. One piece of this includes the following code: <a [routerLink]="[]" class="image-fav" (click)="imageDel()">CLICK-ME</a> Despite setting up the click event to call the imageDel funct ...

I am experiencing difficulties with implementing Angular material components in my project

I recently encountered an issue while trying to integrate angular material into my project. Despite importing the MatFormFieldModule, I received the following error: ERROR in src/app/login/components/login/login.component.html:2:1 - error NG8001: &apo ...

waiting list and signal barrier

The book "Advanced Programming in the Unix Environment" explains the handling of signals in the following way: Signals are not queued by the kernel unless it supports the real-time extensions to POSIX.1 If a blocked signal is generated multiple times (wi ...

Angular2: The provided arguments do not correspond to any valid call signature

I have developed my own Observable service implementation import { Injectable, EventEmitter, Output} from '@angular/core'; @Injectable() export class CustomObservableService { data = []; @Output eventEmitter:EventEmitter = new EventEmit ...

Deploying AngularApp with Cordova on iOS results in a blank screen

Encountering a White Screen Issue on iOS While Trying to Load an Angular App with Cordova. After modifying the base href to "./" in my Angular app project, it runs smoothly on all platforms except for iOS. Any ideas why it's not loading properly on iO ...

Utilizing Angular: Integrating the Http response output into a map

I have a situation where I am making multiple HTTP calls simultaneously from my Angular application. The goal is to store the responses of these calls in a Map. data: Map<number, any> = new map<number,any>(); --------------------------------- ...

Is there a way to conceal the horizontal divider in the login form of the ionic HTML mobile user interface?

While designing this login form on the HTML ionic mobile UI, everything looks good except for one thing - I want to hide the horizontal line that appears between the "Forgot Password" label and the LOGIN button. Is there a way to do this? Login.html: < ...

Assign a value to a FormControl in Angular 6

I have 60 properties linked to 60 controls through the mat-tab in a form. When it comes to editing mode, I need to assign values to all the controls. One approach is as follows: this.form.controls['dept'].setValue(selected.id); This involves l ...

Having trouble retrieving the default selected value using the index in Angular Material's mat-button-toggle functionality

I'm encountering an issue with setting the default value for a toggle button group. The code is simple and the toggle buttons are correctly fetching values from the index, but I can't seem to get one of them to be default selected. I tried settin ...

Experiencing a strange response while attempting to parse the result of an Angular 2 HTTP JSON request

After successfully implementing the http.get call and retrieving data from the request, I encountered an issue: this.http.get('https://data.cityofnewyork.us/resource/xx67-kt59.json').subscribe(data => { // Read the result field from the ...

Specifying the return type of a function as a combination of the types of the input arguments

Is there a way to safely implement the given function in TypeScript without using unsafe casts or an extensive number of function overloads with various input permutations? interface Wrapped<T> { type: string; data: T; } interface WrappedA&l ...

How to dynamically load a component within a class-based Vue component

I am facing an issue with loading two components dynamically using an object map. Info (options-based) SearchBar (class-based) While it works for the options-based component, I encounter an error stating _currentTab is undefined when trying to load a si ...

Having trouble sending correct true/false values for selected radio buttons on an Angular5 table, often requiring users to click them twice to submit the appropriate values

My goal is to assign true or false values to selected radio buttons in each row and then form an object for submission. To distinguish between the radio button values in each row, I have used {{k}}+{{sizeobj.rbSelected}} as the value which is causing issue ...

Activating the loader dismiss command will transition the swiper to the current page

Having a swiper and loader makes the scenario very straightforward. The loader is initialized whenever calculations are performed, and after successfully obtaining the result, the loader turns off and swipes to the second slide. <swiper-container #sl ...

Error: The template is unable to parse due to unrecognized element 'mat-label'

When attempting to write about the datepicker, I encountered the following error: Uncaught Error: Template parse errors: 'mat-label' is not a recognized element: If 'mat-label' is an Angular component, please ensure that it is part o ...

403 Error: Access Denied for Spring Cloud Gateway

Scenario In the development of my project, I have opted for a MicroServices architecture. Specifically, I am utilizing Angular 15 for the Frontend and Spring 3.0.2 as the Backend technology. To manage authentication for both the frontend and backend, I ha ...

Retrieve the weekday dates for a specific year, month, and relative week number using Javascript or Typescript

I am in need of a custom function called getDaysOfWeekDates that can take a year, a month (ranging from 0 to 11), and the week number of each month (usually 4-5 weeks per month) as parameters, and return a list of dates containing each day of that particul ...