# Signal Input : comment ça marche ?

Dans notre précédent article [Angular Signals : que faut-il retenir quand je débute ?](https://angulardev.fr/angular-signals-que-faut-t-il-retenir-quand-je-debute), nous avons exploré ce qui se cache derrière les `Signals` en `Angular`. Aujourd'hui, nous aborderons l'un des concepts liés aux `Angular Signals` : les `Signal Inputs`, comme l'indique le titre de l'article. L'objectif est de comprendre ce que c'est, comment l'utiliser et pourquoi l'utiliser.

### Qu'est-ce qu'un `Signal Input` en Angular ?

Avant de définir ce qu'est un `Signal Input`, faisons un peu d'histoire. En `Angular`, pour passer des propriétés d'un *composant parent A* à un *composant enfant B*, nous utilisons habituellement les `@Input()`. Voici un exemple :

```typescript
import {Component, input} from '@angular/core';
@Component({...})
export class ComponentB {
  @Input() age: number;
}

<!--- Parent component side (ComponentA) --->
<component-b [age]='10' />
```

Avec l'arrivée de `Signal` en `Angular`, la core team de `Angular` a introduit une nouvelle méthode pour gérer cette communication, appelée `Signal Input`, afin d'optimiser les performances du framework.

Le `Signal Input` joue le même rôle que `@Input()`***c'est-à-dire permettre l'injection de données du composant parent A vers le composant enfant B.***

### Comment utiliser un Signal Input ?

Angular prend en charge deux variantes de `Signal Input` à savoir :

* `Optional input` : Il faut souligner que le `Signal Input` est ***optionnel par défaut***. Tout comme le `@Input()`, si au niveau du *composant parent A*, nous ne faisons pas passer l'input en propriété au *composant enfant B*, ce n'est pas bloquant. Voici un exemple de composant utilisant le Optional Signal Input :
    
    ```typescript
    import {Component, input} from '@angular/core';
    @Component({...})
    export class MyComp {
      // optional
      firstName = input<string>();         // InputSignal<string|undefined>
      age = input(0);                      // InputSignal<number>
    }
    ```
    
    Pour le `Signal Input` nommé `firstName`, on note que le type est `string | undefined`. En effet, si l'on ne spécifie pas une valeur initiale à un `Signal Input` qui optionnel même après l'avoir typé, `Angular` utilisera le type `undefined` de façon implicite. ***Il faut donc penser à initialiser votre***`Signal Input`***avec une valeur quand il est optionnel.***
    
* `Required input` : Ici, le `Signal Input` est rendu obligatoire et il est nécessaire d'indiquer le type de la donnée à recevoir. En voici un exemple :
    
    ```typescript
    import {Component, input} from '@angular/core';
    @Component({...})
    export class MyComp {
      // required
      lastName = input.required<string>(); // InputSignal<string>
    }
    ```
    

Tout comme le `@Input()` classique que nous connaissons jusque-là, le `Signal Input` aussi peut être utilisé avec des `alias`. Le but des `alias` c'est d'éviter des conflits de noms d'attributs. Voici un exemple lié à l'utilisation d'un `alias` sur un `Signal Input` :

```typescript
import {Component, input} from '@angular/core';
@Component({...})
export class MyComp {
  age = input(0, {alias: 'studentAge'});
}

<!--- Parent component side --->
<my-comp [studentAge]='10' />
```

A présent, nous parlerons d'une spécifité propre au `Signal Input` que nous n'avons pas avec `@Input()`. Il s'agit de la ***transformation de valeur*** \[*cette expression fait penser aux Pipes 😃\].* En effet, tout comme la philosophie derrière un `Pipe`, nous sommes capables avec un `Signal Input`***de faire un traitement sur la valeur d'entrée sans en modifier le sens. La transformation convertira donc la valeur brute envoyée par le parent au type d'entrée attendu. La transformation doit être une fonction pure.*** En voici une illustration :

```typescript
class MyComp {
  disabled = input(false, {
    transform: (value: boolean|string) => typeof value === 'string' ? value === '' : value,
  });
}
```

Dans l'exemple ci-dessus, nous déclarons un `Signal Input` nommé `disabled` qui accepte des valeurs de type `boolean` et `string`. ***Ces valeurs (peu importe quelles soient***`boolean`***ou***`string`***) sont ensuite traitées en***`boolean`***avec la transformation, ce qui donne des***`boolean`***.***

De cette façon, nous ne traitons que du `boolean` à l'intérieur de notre *composant enfant* lorsque nous appelons `this.disabled()`, tandis au niveau de notre *composant parent,* nous pouvons passer un `string` comme raccourci pour marquer notre composant `disabled`.

> Pour finir, tout ce qui a été abordé dans ce précédent [article](https://angulardev.fr/angular-signals-que-faut-t-il-retenir-quand-je-debute) concernant les `Signals` est valable pour les `Signal Inputs` à savoir les méthodes `computed()` et `effect()`.

### Pourquoi et quand faut t-il choisir Signal Input au lieu de `@Input()` ?

Le `Signal Input` est une alternative réactive à la méthode `@Input()`. Voici les nombreux avantages qu'offrent un `Signal Input` en nous basant sur la documentation :

* Le `required input` de `Signal Input` ne nécessite pas de valeur initiale ou d'astuce pour indiquer à `TypeScript` qu'un `input` a toujours une valeur.
    
* Les transformations (`transform`) sont automatiquement vérifiées pour correspondre aux valeurs acceptées.
    
* Les `Signal Inputs`, lorsqu'ils sont utilisées dans des *templates*, marqueront automatiquement les composants `OnPush` en `dirty`. ***Avec***`@Input()`***, il fallait le faire soi-même pour permettre le changement de détection.***
    
* L'utilisation de la méthode `effect()` au lieu de `ngOnChanges()` ou `setters` qui rend plus facile et aisé le contrôle du changement des valeurs.
    

En somme, nous avons à présent une compréhension plus poussée de l'essentiel à connaître sur les `Signal Inputs.` Nous aborderons dans de prochains articles, d'autres concepts liés à `Angular Signal`.

> Pour plus d'informations 👉 [Signal Inputs](https://angular.dev/guide/signals/inputs)
