Erreur 1 : Injection de Dépendances non utilisée
Le problème
Description : Lorsque vous utilisez une dépendance dans votre service ou composant Angular mais que vous ne l'utilisez pas, Angular peut générer une erreur car cela signifie qu'il n'y a pas besoin d'injecter cette dépendance. Par exemple :
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient, private unusedService: UnusedService) {} }Code d'exemple :
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-example', template: `<div></div>` }) export class ExampleComponent { constructor(private http: HttpClient, private unusedService: UnusedService) {} }
Pourquoi c'est une erreur
- Impact sur la performance : L'injection inutile de dépendances peut augmenter le temps de démarrage et l'utilisation de la mémoire de votre application.
- Impact sur la sécurité : Si une dépendance inutile est utilisée, elle pourrait potentiellement contenir des vulnérabilités non nécessaires.
- Impact sur la maintenabilité : Des dépendances inutiles rendent le code plus complexe et difficile à comprendre.
La solution
Code corrige :
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-example', template: `<div></div>` }) export class ExampleComponent { constructor(private http: HttpClient) {} }Explication : Dans ce code corrigé, nous avons supprimé la dépendance inutile
UnusedServicede la liste des paramètres du constructeur.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
no-unused-varspour détecter les variables et les dépendances non utilisées.{ "rules": { "no-unused-vars": ["error", { "varsIgnorePattern": "_unused" }] } } - Pattern : Assurez-vous de ne pas ajouter des dépendances dans le constructeur si elles ne sont pas nécessaires.
- Habitude à adopter : Utilisez un outil comme
ng lintpour vérifier votre code et détecter les erreurs potentialles.
Erreur 2 : Utilisation de any sans validation
Le problème
Description : L'utilisation excessive du type
anydans Angular signifie que TypeScript n'effectue pas la validation de类型 de données, ce qui peut entraîner des erreurs à l'exécution. Par exemple :import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>user</div>` }) export class ExampleComponent { user: any = { name: 'John', age: 30 }; }Code d'exemple :
import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>data</div>` }) export class ExampleComponent { data: any = JSON.parse('{"name": "John", "age": 30}'); }
Pourquoi c'est une erreur
- Impact sur la performance : L'utilisation de
anypeut rendre le code moins performant car il n'y a pas de validation des types. - Impact sur la sécurité : Les données non typées peuvent être exploitées par des attaquants en injectant des données malformées.
- Impact sur la maintenabilité : Le code qui utilise
anyest plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>user.name - user.age</div>` }) export class ExampleComponent { user = { name: 'John', age: 30 }; }Explication : Dans ce code corrigé, nous avons défini le type de
usercomme un objet avec des propriétés nommées.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
@typescript-eslint/no-explicit-anypour éviter l'utilisation deany.{ "rules": { "@typescript-eslint/no-explicit-any": "error" } } - Pattern : Assurez-vous d'utiliser des types spécifiques plutôt que
anylorsque c'est possible. - Habitude à adopter : Utilisez le type
anyuniquement en dernier recours et vérifiez toujours les données avant de les utiliser.
Erreur 3 : Manque de gestion des erreurs asynchrones
Le problème
Description : Lorsque vous effectuez une requête HTTP ou tout autre traitement asynchrone dans Angular, il est crucial de gérer les erreurs pour éviter des crashs à l'exécution. Par exemple :
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-example', template: `<div>user</div>` }) export class ExampleComponent { user: any; constructor(private http: HttpClient) { this.http.get('https://api.example.com/user').subscribe(); } }Code d'exemple :
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-example', template: `<div>user</div>` }) export class ExampleComponent { user: any; constructor(private http: HttpClient) { this.http.get('https://api.example.com/user').subscribe( (data) => { this.user = data; }, (error) => { console.error(error); } ); } }
Pourquoi c'est une erreur
- Impact sur la performance : Si des erreurs sont non gérées, elles peuvent entraîner des crashs à l'exécution, ce qui peut affecter les performances de l'application.
- Impact sur la sécurité : Les erreurs non gérées peuvent révéler des informations sensibles sur votre application, ce qui peut être utilisée par des attaquants.
- Impact sur la maintenabilité : L'absence de gestion des erreurs rend le code plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-example', template: `<div>user</div>` }) export class ExampleComponent { user: any; constructor(private http: HttpClient) { this.http.get('https://api.example.com/user').subscribe( (data) => { this.user = data; }, (error) => { console.error(error); // Gérer l'erreur de manière appropriée } ); } }Explication : Dans ce code corrigé, nous avons ajouté une gestion des erreurs pour gérer les erreurs potentielles lors de la requête HTTP.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
@typescript-eslint/no-catch-allpour encourager l'utilisation de blocscatchspécifiques.{ "rules": { "@typescript-eslint/no-catch-all": "error" } } - Pattern : Assurez-vous d'utiliser des blocs
try...catchou des observables avec des gestionnaires de erreurs pour gérer les erreurs asynchrones. - Habitude à adopter : Toujours prévoir une gestion des erreurs lors de l'utilisation de fonctionnalités asynchrones.
Erreur 4 : Utilisation inappropriée des pipes
Le problème
Description : L'utilisation excessive ou inappropriée des pipes dans Angular peut affecter les performances et rendre le code plus difficile à maintenir. Par exemple :
import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>user | json</div>` }) export class ExampleComponent { user = { name: 'John', age: 30 }; }Code d'exemple :
import { Component } from '@angular/core'; import { DatePipe } from '@angular/common'; @Component({ selector: 'app-example', template: `<div>date | date:'fullDate'</div>` }) export class ExampleComponent { date = new Date(); }
Pourquoi c'est une erreur
- Impact sur la performance : Les pipes sont exécutés à chaque changement de cycle de vie du composant, ce qui peut entraîner des performances dégradées si ils ne sont pas optimisés.
- Impact sur la sécurité : Les pipes peuvent potentiellement contenir des vulnérabilités non nécessaires ou être utilisés pour injecter du code malveillant.
- Impact sur la maintenabilité : Le code qui utilise de nombreux pipes peut être plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>user | json</div>` }) export class ExampleComponent { user = { name: 'John', age: 30 }; }Explication : Dans ce code corrigé, nous avons utilisé le pipe
jsonde manière appropriée pour formatter l'objetuser.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
angular/template-i18n-pipepour encourager l'utilisation du pipe i18n plutôt que des pipes personnalisés.{ "rules": { "angular/template-i18n-pipe": "error" } } - Pattern : Assurez-vous d'utiliser les pipes de manière appropriée et limitées dans votre code.
- Habitude à adopter : Utilisez des pipes personnalisés uniquement si nécessaire et optimisés.
Erreur 5 : Manque de validation des formulaires
Le problème
Description : Lorsqu'un formulaire est soumis dans Angular, il est crucial de valider les données avant de les traiter pour éviter des erreurs à l'exécution. Par exemple :
import { Component } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-example', template: ` <form [formGroup]="form"> <input formControlName="name" /> <button type="submit">Submit</button> </form> ` }) export class ExampleComponent { form: FormGroup; constructor(private fb: FormBuilder) { this.form = this.fb.group({ name: '' }); } }Code d'exemple :
import { Component } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-example', template: ` <form [formGroup]="form" (ngSubmit)="onSubmit()"> <input formControlName="name" /> <button type="submit">Submit</button> </form> ` }) export class ExampleComponent { form: FormGroup; constructor(private fb: FormBuilder) { this.form = this.fb.group({ name: '' }); } onSubmit() { const name = this.form.value.name; // Traiter le nom } }
Pourquoi c'est une erreur
- Impact sur la performance : Si des formulaires non validés sont soumis, elles peuvent entraîner des performances dégradées lors du traitement des données.
- Impact sur la sécurité : Les formulaires non validés peuvent être utilisés pour injecter des données malveillantes ou des informations sensibles.
- Impact sur la maintenabilité : L'absence de validation de formulaires rend le code plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-example', template: ` <form [formGroup]="form" (ngSubmit)="onSubmit()"> <input formControlName="name" /> <button type="submit">Submit</button> </form> ` }) export class ExampleComponent { form: FormGroup; constructor(private fb: FormBuilder) { this.form = this.fb.group({ name: ['', Validators.required] }); } onSubmit() { if (this.form.valid) { const name = this.form.value.name; // Traiter le nom } else { console.error('Formulaire invalide'); } } }Explication : Dans ce code corrigé, nous avons ajouté une validation de formulaire pour s'assurer que le champ
nameest rempli avant de soumettre le formulaire.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
@angular-eslint/template/form-control-bindingpour encourager l'utilisation des directives formControl et formControlName.{ "rules": { "@angular-eslint/template/form-control-binding": "error" } } - Pattern : Assurez-vous d'utiliser les directives formControl et formControlName pour lier les contrôles de formulaire à votre modèle.
- Habitude à adopter : Toujours valider les formulaires avant de les soumettre.
Erreur 6 : Utilisation de ViewChild avec des dépendances non injectables
Le problème
Description : L'utilisation de
@ViewChildpour accéder à un élément du DOM ou à une directive qui n'est pas injectable peut entraîner des erreurs à l'exécution. Par exemple :import { Component, ViewChild } from '@angular/core'; @Component({ selector: 'app-example', template: `<div #myElement>Hello World</div>` }) export class ExampleComponent { @ViewChild('myElement') myElement: ElementRef; }Code d'exemple :
import { Component, ViewChild } from '@angular/core'; @Component({ selector: 'app-example', template: `<div #myDirective>Hello World</div>` }) export class ExampleComponent { @ViewChild('myDirective') myDirective: MyDirective; }
Pourquoi c'est une erreur
- Impact sur la performance : L'utilisation de
@ViewChildavec des dépendances non injectables peut entraîner des performances dégradées car Angular doit rechercher l'élément du DOM ou la directive. - Impact sur la sécurité : L'accès direct à un élément du DOM ou à une directive peut potentiellement être utilisé pour injecter du code malveillant.
- Impact sur la maintenabilité : Le code qui utilise
@ViewChildavec des dépendances non injectables est plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component, ViewChild } from '@angular/core'; import { ElementRef } from '@angular/core'; @Component({ selector: 'app-example', template: `<div #myElement>Hello World</div>` }) export class ExampleComponent { @ViewChild('myElement') myElement: ElementRef; }Explication : Dans ce code corrigé, nous avons utilisé
@ViewChildavec un élément du DOM qui est injectable.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
angular/no-viewchild-elementrefpour encourager l'utilisation de ElementRef plutôt que des éléments du DOM.{ "rules": { "angular/no-viewchild-elementref": "error" } } - Pattern : Assurez-vous d'utiliser
@ViewChildavec des éléments du DOM qui sont injectables ou avec des directives personnalisées. - Habitude à adopter : Toujours utiliser
@ViewChildavec des éléments du DOM ou des directives personnalisées.
Erreur 7 : Utilisation de ngZone pour exécuter des tâches hors du cycle de rendu
Le problème
Description : L'utilisation de
NgZonepour exécuter des tâches hors du cycle de rendu peut entraîner des performances dégradées et des problèmes de synchronisation. Par exemple :import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { constructor(private ngZone: NgZone) {} doSomething() { this.ngZone.runOutsideAngular(() => { // Exécuter des tâches hors du cycle de rendu }); } }Code d'exemple :
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { constructor(private ngZone: NgZone) {} doSomething() { this.ngZone.runOutsideAngular(() => { // Exécuter des tâches hors du cycle de rendu }); } }
Pourquoi c'est une erreur
- Impact sur la performance : L'utilisation de
NgZonepour exécuter des tâches hors du cycle de rendu peut entraîner des performances dégradées car Angular doit gérer les changements manuellement. - Impact sur la sécurité : L'exécution de code hors du cycle de rendu peut potentiellement être utilisé pour injecter du code malveillant.
- Impact sur la maintenabilité : Le code qui utilise
NgZonepour exécuter des tâches hors du cycle de rendu est plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { constructor(private ngZone: NgZone) {} doSomething() { this.ngZone.runOutsideAngular(() => { // Exécuter des tâches hors du cycle de rendu }); } }Explication : Dans ce code corrigé, nous avons utilisé
NgZonepour exécuter des tâches hors du cycle de rendu.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
angular/no-run-outside-angularpour encourager l'utilisation de la méthode appropriée pour exécuter des tâches hors du cycle de rendu.{ "rules": { "angular/no-run-outside-angular": "error" } } - Pattern : Assurez-vous d'utiliser la méthode appropriée pour exécuter des tâches hors du cycle de rendu.
- Habitude à adopter : Toujours utiliser
NgZonepour exécuter des tâches hors du cycle de rendu.
Erreur 8 : Utilisation de ChangeDetectorRef pour forcer la mise à jour du DOM
Le problème
Description : L'utilisation de
ChangeDetectorRefpour forcer la mise à jour du DOM peut entraîner des performances dégradées et des problèmes de synchronisation. Par exemple :import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { constructor(private cdr: ChangeDetectorRef) {} updateDOM() { // Mettre à jour le DOM this.cdr.detectChanges(); } }Code d'exemple :
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { constructor(private cdr: ChangeDetectorRef) {} updateDOM() { // Mettre à jour le DOM this.cdr.detectChanges(); } }
Pourquoi c'est une erreur
- Impact sur la performance : L'utilisation de
ChangeDetectorRefpour forcer la mise à jour du DOM peut entraîner des performances dégradées car Angular doit gérer les changements manuellement. - Impact sur la sécurité : L'exécution de code pour mettre à jour le DOM peut potentiellement être utilisé pour injecter du code malveillant.
- Impact sur la maintenabilité : Le code qui utilise
ChangeDetectorRefpour forcer la mise à jour du DOM est plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { constructor(private cdr: ChangeDetectorRef) {} updateDOM() { // Mettre à jour le DOM this.cdr.detectChanges(); } }Explication : Dans ce code corrigé, nous avons utilisé
ChangeDetectorRefpour forcer la mise à jour du DOM.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
angular/no-change-detector-ref-detect-changespour encourager l'utilisation de la méthode appropriée pour mettre à jour le DOM.{ "rules": { "angular/no-change-detector-ref-detect-changes": "error" } } - Pattern : Assurez-vous d'utiliser la méthode appropriée pour mettre à jour le DOM.
- Habitude à adopter : Toujours utiliser
ChangeDetectorRefpour forcer la mise à jour du DOM.
Erreur 9 : Utilisation de HostListener avec des événements non standard
Le problème
Description : L'utilisation de
@HostListenerpour écouter des événements non standard peut entraîner des problèmes de compatibilité et des erreurs à l'exécution. Par exemple :import { Component, HostListener } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { @HostListener('customEvent') handleCustomEvent() { // Gérer l'événement } }Code d'exemple :
import { Component, HostListener } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { @HostListener('customEvent') handleCustomEvent() { // Gérer l'événement } }
Pourquoi c'est une erreur
- Impact sur la performance : L'utilisation de
@HostListenerpour écouter des événements non standard peut entraîner des problèmes de compatibilité et des erreurs à l'exécution. - Impact sur la sécurité : L'écoute d'événements non standard peut potentiellement être utilisé pour injecter du code malveillant.
- Impact sur la maintenabilité : Le code qui utilise
@HostListenerpour écouter des événements non standard est plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component, HostListener } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { @HostListener('click') handleClick() { // Gérer le clic } }Explication : Dans ce code corrigé, nous avons utilisé
@HostListeneravec un événement standard.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
angular/no-hostlistener-custom-eventpour encourager l'utilisation d'événements standards.{ "rules": { "angular/no-hostlistener-custom-event": "error" } } - Pattern : Assurez-vous d'utiliser
@HostListeneravec des événements standards. - Habitude à adopter : Toujours utiliser
@HostListeneravec des événements standards.
Erreur 10 : Utilisation de ViewChild pour accéder à des éléments du DOM non injectables
Le problème
Description : L'utilisation de
@ViewChildpour accéder à des éléments du DOM non injectables peut entraîner des erreurs à l'exécution. Par exemple :import { Component, ViewChild } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { @ViewChild('myElement') myElement: HTMLElement; ngAfterViewInit() { console.log(this.myElement); } }Code d'exemple :
import { Component, ViewChild } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { @ViewChild('myElement') myElement: HTMLElement; ngAfterViewInit() { console.log(this.myElement); } }
Pourquoi c'est une erreur
- Impact sur la performance : L'utilisation de
@ViewChildpour accéder à des éléments du DOM non injectables peut entraîner des erreurs à l'exécution. - Impact sur la sécurité : L'accès à des éléments du DOM non injectables peut potentiellement être utilisé pour injecter du code malveillant.
- Impact sur la maintenabilité : Le code qui utilise
@ViewChildpour accéder à des éléments du DOM non injectables est plus difficile à comprendre et à maintenir.
La solution
Code corrige :
import { Component, ViewChild } from '@angular/core'; @Component({ selector: 'app-example', template: `<div>Hello World</div>` }) export class ExampleComponent { @ViewChild('myElement') myElement: HTMLElement; ngAfterViewInit() { console.log(this.myElement); } }Explication : Dans ce code corrigé, nous avons utilisé
@ViewChildavec un élément du DOM injectable.
Comment prévenir
- Règle ESLint : Utiliser les règles ESLint comme
angular/no-viewchild-non-injectable-elementpour encourager l'utilisation de@ViewChildavec des éléments du DOM injectables.{ "rules": { "angular/no-viewchild-non-injectable-element": "error" } } - Pattern : Assurez-vous d'utiliser
@ViewChildavec des éléments du DOM injectables. - Habitude à adopter : Toujours utiliser
@ViewChildavec des éléments du DOM injectables.