Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 6503

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 27, 20242024-11-27T07:09:14+00:00 2024-11-27T07:09:14+00:00

Angular Signal Inputs: road to Signal Components

  • 60k

Angular v17.1.0 has been released recently and it introduced a new amazing input API designed to enable early access to Signal Inputs.

Signal Inputs introduction is the initial act of the upcoming rise of Signal Components and zoneless Angular application, enhancing already both code quality and developer experience. Let’s delve into how they work.

TL;DR: new signal inputs finally arrived in the Angular ecosystem<br>


Bye @Input decorator; Welcome input( ) function

Creating a Signal Input is quite simple:
rather than creating an input using the @Input decorator, you should now use the input() function provided by @angular/core.

Let’s see an example creating an input of string type:

import { Component, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   myProp = input<string>(); } 
Enter fullscreen mode Exit fullscreen mode

Using the input() function your inputs will be typed as InputSignal, a special type of read-only Signal defined as following:

An InputSignal is similar to a non-writable signal except that it also carries additional type-information for transforms, and that Angular internally updates the signal whenever a new value is bound.

More specifically your Signal Inputs will be typed as the following:

myProp: InputSignal<ReadT, WriteT = ReadT> = input<ReadT>(...) 
Enter fullscreen mode Exit fullscreen mode

Where ReadT represents the type of the signal value and WriteT represents the type of the expected value from the parent.
Although these types are often the same, I’ll delve deeper into their role and differences discussing the transform function later on.

Let’s go back to the previous example focusing on the input value type:

import { Component, InputSignal, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   myProp: InputSignal<string | undefined, string | undefined> = input<string>(); } 
Enter fullscreen mode Exit fullscreen mode

Those undefined are given by the optional nature of the input value.

To define your input as required, and thus get rid of those nasty undefined, the input API offers a dedicated required() function:

import { Component, InputSignal, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   myProp: InputSignal<string, string> = input.required<string>(); } 
Enter fullscreen mode Exit fullscreen mode

Alternatively you can provide a default value to the input() function:

import { Component, InputSignal, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   myProp: InputSignal<string, string> = input<string>(''); } 
Enter fullscreen mode Exit fullscreen mode


No more ngOnChanges()

Nowadays you typically use ngOnChanges and setter functions to perform actions when an input is updated.

With Signal Inputs you can take advantage of the great flexibility of Signals to get rid of those functions using two powerful tools: computed() and effect().

Computed Signals

Using computed() you can easily define derived values starting from your inputs, one or more, that will be always updated based on the latest values:

import { Component, InputSignal, Signal, computed, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   description: InputSignal<string, string> = input<string>('');    descriptionLength: Signal<number> = computed(() => this.description.length); } 
Enter fullscreen mode Exit fullscreen mode

So each time description value is modified, the value of descriptionLength is recalculated and updated accordingly.

Effect

With effect() you can define side effects to run when your inputs, one or more, are updated.

For example, imagine you need to update a third-party script you are using to build your chart component when an input is updated:

import Chart from 'third-party-charts'; import { effect, Component, InputSignal, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   chartData: InputSignal<string[], string[]> = input.required<string[]>();    constructor() {     const chart = new Chart({ ... });      effect((onCleanup) => {       chart.updateData(this.chartData());        onCleanup(() => {         chart.destroy();       });     });   } } 
Enter fullscreen mode Exit fullscreen mode

Or even perform an http request:

import { HttpClient } from '@angular/common/http'; import { effect, Component, InputSignal, inject, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   myId: InputSignal<string, string> = input.required<string>();    response: string = '';    constructor() {     const httpClient = inject(HttpClient);      effect((onCleanup) => {       const sub = httpClient.get<string>(`myurl/${this.myId()}/`)         .subscribe((resp) => { this.response = resp });        onCleanup(() => {         sub.unsubscribe();       });     });   } } 
Enter fullscreen mode Exit fullscreen mode

Using computed() and effect() will make your components more robust and optimized, enhancing also a lot the maintainability of the code.


Alias and transform function

In order to guarantee a smoother migration from decorator-based inputs, Signal Inputs supports also alias and transform function properties:

import { HttpClient } from '@angular/common/http'; import { effect, Component, InputSignal, inject, input } from '@angular/core';  @Component({ ... }) export class MyComponent {   textLength: InputSignal<number, string> = input<number, string>(0, {     alias: 'descriptionText',     transform: (text) => text.length   }); } 
Enter fullscreen mode Exit fullscreen mode

In particular, thanks to transform function you can define a function that manipulates your input before it is available in the component scope and this is where the difference between ReadT and WriteT comes into play.

In fact using the transform function can create a mismatch between the type of the value being set from the parent, represented by WriteT, and the type of the value stored inside your Signal Input, represented by ReadT.

For this reason, when creating a Signal Input with the transform function you can specify both ReadT and WriteT as the function type arguments:

mySimpleProp: InputSignal<ReadT, WriteT = ReadT> = input<ReadT>(...)  myTransformedProp: InputSignal<ReadT, WriteT> = input<ReadT, WriteT>( ... , {   transform: transformFunction }); 
Enter fullscreen mode Exit fullscreen mode

As you can see, without the transform function the value of WriteT is set as identical to ReadT, while using the transform function both ReadT and WriteT are defined distinctly.


What about two-way binding?

There is no way to implement two-way binding with Signal Inputs, but there is a dedicated API called Model Input that exposes an update() function to fulfill this behavior.

👇🏼 You can find my dedicated article here: 👇🏼

davidepassafaro

Angular Model Inputs: two-way binding inputs with Signals

Davide Passafaro ・ Apr 9

#angular #frontend #webdev #javascript


Thanks for reading so far 🙏

I’d like to have your feedback so please leave a comment, like or follow. 👏

And if you really liked it please follow me on LinkedIn. 👋

angularfrontendjavascriptwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 2k
  • Popular
  • Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers
  • Author

    Refactoring for Efficiency: Tackling Performance Issues in Data-Heavy Pages

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.