Components with Angular

Updated on: 01/31/2025 Danny
Version Française


Components will allow us to structure our Angular application.

We will create our first components with Angular CLI and Typescript .
intro alt 00001

What we are going to do

  • Before You Begin
    What is a component?

  • Angular and Components
    How does Angular handle the notion of components?

  • Creating our Angular project
    We will use an existing project containing the essential functionality.
    The project was generated with Angular CLI .
    It uses Routing and Lazy Loading .
    It integrates the Bootstrap CSS Framework.

  • Adapt our application
    We will create a Components page to be able to perform all our tests

  • Creating a first component
    Use Angular CLI to create this component

  • Concept of Input and Output
    Communicating with components

  • Perform the Tests
    Unitary and end to end.

  • Source code
    The full project code on github.

What is a component?

We will create and manipulate components with Angular.

Before that we need to understand four important words

  • Classes
  • Objects
  • Instances
  • Components

For this, let's take the simple example of a smartphone and try to apply it to these words.

What is an Angular component?

Here a class is a smartphone

We could replace class with other synonyms

  • Mold
  • Recipe
  • Formula

The class is all the information needed to create objects. It is our mold.

With this class we will create objects.
We could replace the word object with the word component.

In our example an iPhone 7 or a Galaxy A10 are objects or components created from the Smarthpone class .

So let's create an object.

Components et classes

The action that allows you to create an object from a class is called

  • Instantiation

From a class we create an instance which will ultimately be our object or component .


Components and Object Programming

Programming that allows you to create or manipulate objects is called

  • POO
    O bject - Oriented Programming
    or O bject - Oriented P rogramming: OOP in English

Object Oriented Programming was invented in the early 1960s.
OOP imagines a program as an arrangement of software bricks.

This type of programming is based on the definition and interaction of these bricks (or objects ).

This programming obviously uses a programming language ( computer language in English)

There are two types of object-oriented programming language.

  • Classful languages
    Java, C++, Python, Ruby

  • Prototype languages
    Javascript

Noticed :
As we will see a little later, Javascript has also become a class-based language.


Conclusion on the components

An object or component is a representation of a material or immaterial thing in reality and has

  • Properties
    These are the characteristics specific to this object.
    Synonyms for properties could be attributes , data , members , or variables.

  • Actions
    These are all the actions applicable to this object
    Synonyms for actions could be methods , or operations.

Class

  • It is a data model.
  • It allows you to define a structure.
  • It is a kind of mold from which all objects will be created.


Instance

  • It is a particular representation of a class.
  • Creating an object therefore consists of calling an instance of the class.

Instantiation

  • It is the creation of an object from a class.
  • The object thus created will have the name of the class as its type.
  • A synonym for instantiation would be occurence .

Let's go back to our example.

Smartphone is a class and has

  • 4 properties
    Name
    Model
    Price
    Year


  • 3 Actions
    Buy

    Sell
    To rent out

IPhone XR is an object whose properties are

  • Name : iPhone XR
  • Model : Apple
  • Price : 560
  • Year : 2018

How to declare a simple smartphone class?
The class will therefore be called smartphone .
We will use the keyword class , followed by the name of the class we are declaring.


Angular and Components

An Angular component is an object based on the principles we discussed in this course.

What are the interests of the components?

  • A component defines an area of interaction in the user interface (UI)
  • Allows reuse

In Angular a component is made up of 3 elements:

  • A component class
    It manages data and features

  • an HTML template (HTML template)
    It determines what is visually presented to the user

  • Component-specific styles
    They define the look of the component.

Angular recommends best practices, that is to say a way of writing our application which follows certain rules.
We will explain these rules in another course.

To put it simply, let's imagine a component called a smartphone .
This component would thus be composed according to the theories mentioned previously of 3 files.

  • smartphone.component.html
  • smartphone.component.css
  • smartphone.component.ts


The component would be called

  • for the graphic part
    <app-smartphone>
  • for the logical part
    SmartphoneComponent


An Angular application is made up of a tree of components.
Each component having a specific objective and responsibility.

Now let's test all these theories in an Angular application.


Creating the Angular project

To be able to continue this tutorial we obviously need to have certain elements

  • Node.js : The JavaScript platform
  • Git : The version control software.
  • Angular CLI : The tool provided by Angular.
  • Visual Studio Code : A code editor.

You can check out the following tutorial which explains in detail how to do it


We will use an existing project whose characteristics are

  • Generated with Angular CLI
  • Routing
  • Lazy loading
  • Using the Bootstrap CSS Framework
# Créez un répertoire demo (le nom est ici arbitraire)
mkdir demo

# Allez dans ce répertoire
cd demo

# Récupérez le code source sur votre poste de travail
git clone https://github.com/ganatan/angular-react-bootstrap.git

# Allez dans le répertoire qui a été créé
cd angular-react-bootstrap
cd angular

# Exécutez l'installation des dépendances (ou librairies)
npm install

# Exécutez le programme
npm run start

# Vérifiez son fonctionnement en lançant dans votre navigateur la commande
http://localhost:4200/

New Feature

We will add a page dedicated to components in our project.
This is where we will do all of our component testing and modifications.
ng generate component modules/application/components
ng generate module modules/application/components --routing  --module=app
src/app/app-routing.module.ts
  {
    path: 'components',
    loadChildren: () => import('./modules/application/components/components.module')
      .then(mod => mod.ComponentsModule)
  },
src/app/modules/application/components/components-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { ComponentsComponent } from './components.component';

const routes: Routes = [
  { path: '', component: ComponentsComponent },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class ComponentsRoutingModule { }
src/app/modules/application/components/components.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { ComponentsComponent } from './components.component';
import { ComponentsRoutingModule } from './components-routing.module';

@NgModule({
  imports: [
    CommonModule,
    ComponentsRoutingModule
  ],
  exports: [
    ComponentsComponent
  ],
  declarations: [
    ComponentsComponent
  ],
  providers: [
  ],
})
export class ComponentsModule { }
src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { HomeComponent } from './modules/general/home/home.component';
import { NotFoundComponent } from './modules/general/not-found/not-found.component';
import { AppRoutingModule } from './app-routing.module';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    NotFoundComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Premier Component

All changes will therefore be located in the directory
app/modules/application/components

You just need to copy this directory into your project to test it as you wish.

We will be able to create our first component.
Let's add the following code that you will find below

The classic <h1> and <p> tags for layout
And we call a component that we will call <app-smartphone>
src/app/modules/application/components/components.component.html
<div class="row">
  <div class="text-center col">
    <h1 class="h3">Feature : Components</h1>
    <hr>
  </div>
</div>

<div class="row pb-4">
  <div class="text-center col">
    <app-smartphone></app-smartphone>
  </div>
</div>
If you are using chrome you can switch to debug mode.
Press F12 and console

The result obtained is an error.
'app-smartphone' is not a known element:

What should we do?
We will create this new component using Angular CLI
ng generate component modules/application/components/smartphone

Customize the component

Then we just need to make changes in smartphone.html to see the changes appear in our browser.

Noticed
The name of the component is app-smartphone if you wanted to call it for example nga-smartphone
The prefix parameter located in Angular.json should have been modified
    "angular-starter": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "nga",
}
Let's make a change to our component.
src/app/modules/application/components/smartphone/smartphone.component.html
<div class="card" style="width: 10rem;">
  <div class="card-body">
    <h5 class="card-title">Smartphone</h5>
    <h6 class="card-subtitle mb-2 text-muted">Model</h6>
    <h6 class="card-subtitle mb-2 text-muted">Name</h6>
    <h6 class="card-subtitle mb-2 text-muted">Prize</h6>
    <h6 class="card-subtitle mb-2 text-muted">Name</h6>
  </div>
</div>

Communicating with components

Communication between components can be handled in various ways in Angular.

Inputs and Outputs are one such means.

Let’s start with the Inputs, taking our smartphone example again.

How to do it

  • Using an Input Decorator
  • Add a property


We will gradually use various methods from the simplest to the most complicated.
Until you get a satisfactory method.


Interpolation simple

We will obviously use one of the principles proposed by Angular

  • interpolation .

For more details check the official website here https://angular.io/start

Let's start with a simple Method.

For this we will modify components and smartphone

  • components.ts
  • components.html
  • smartphone.ts
  • smartphone.html

src/app/modules/application/components/smartphone/smartphone.component.ts
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-smartphone',
  templateUrl: './smartphone.component.html',
  styleUrls: ['./smartphone.component.css']
})
export class SmartphoneComponent implements OnInit {

  @Input() name: any;
  @Input() model: any;
  @Input() prize: any;
  @Input() year: any;
  constructor() {
  }

  ngOnInit() {
  }

}
src/app/modules/application/components/smartphone/smartphone.component.html
<div class="card" style="width: 10rem;">
  <div class="card-body">
    <h5 class="card-title">Notre composant</h5>
    <h6 class="card-subtitle mb-2 text-muted">{{ name }}</h6>
    <h6 class="card-subtitle mb-2 text-muted">{{ model }}</h6>
    <h6 class="card-subtitle mb-2 text-muted">{{ prize }}</h6>
    <h6 class="card-subtitle mb-2 text-muted">{{ year }}</h6>
  </div>
</div>
src/app/modules/application/components/components.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-components',
  templateUrl: './components.component.html',
  styleUrls: ['./components.component.css']
})
export class ComponentsComponent implements OnInit {

  name: string;
  model: string;
  prize: string;
  year: string;

  constructor() {
    this.name = 'iPhone XR';
    this.model = 'Apple';
    this.prize = '560';
    this.year = '2018';
  }

  ngOnInit() {
  }

}
src/app/modules/application/components/components.component.html
<div class="row">
  <div class="text-center col">
    <h1 class="h3">Features Components</h1>
    <hr>
  </div>
</div>

<div class="row pb-4">
  <div class="text-center col-4">
    name : {{ name }}<br>
    model : {{ model }}<br>
    prize : {{ prize }}<br>
    year : {{ year }}<br>
  </div>
  <div class="text-center col-8">
    <app-smartphone [name]="name" [model]="model" [prize]="prize" [year]="year"></app-smartphone>
  </div>
</div>
src/app/modules/application/components/components.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ComponentsComponent } from './components.component';
import { SmartphoneComponent } from './smartphone/smartphone.component';

describe('ComponentsComponent', () => {
  let component: ComponentsComponent;
  let fixture: ComponentFixture<ComponentsComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        SmartphoneComponent,
        ComponentsComponent
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ComponentsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Advanced Interpolation

More complex let's create a smartphone.ts file for a json object
src/app/modules/application/components/smartphone/smartphone.ts
export class Smartphone {
  name: string;
  model: string;
  prize: string;
  year: string;
}
src/app/modules/application/components/smartphone/smartphone.component.ts
import { Component, OnInit, Input } from '@angular/core';

import { Smartphone } from './smartphone';

@Component({
  selector: 'app-smartphone',
  templateUrl: './smartphone.component.html',
  styleUrls: ['./smartphone.component.css']
})
export class SmartphoneComponent implements OnInit {

  @Input() smartphone: Smartphone;
  constructor() {
  }

  ngOnInit() {
  }

}
src/app/modules/application/components/smartphone/smartphone.component.html
<div class="card" style="width: 10rem;">
  <div class="card-body">
    <h5 class="card-title">Notre composant</h5>
    <h6 class="card-subtitle mb-2 text-muted">{{ smartphone.name }}</h6>
    <h6 class="card-subtitle mb-2 text-muted">{{ smartphone.model }}</h6>
    <h6 class="card-subtitle mb-2 text-muted">{{ smartphone.prize }}</h6>
    <h6 class="card-subtitle mb-2 text-muted">{{ smartphone.year }}</h6>
  </div>
</div>
src/app/modules/application/components/components.component.ts
import { Component, OnInit } from '@angular/core';

import { Smartphone } from './smartphone/smartphone';

@Component({
  selector: 'app-components',
  templateUrl: './components.component.html',
  styleUrls: ['./components.component.css']
})
export class ComponentsComponent implements OnInit {

  smartphone: Smartphone = new Smartphone();

  constructor() {
    this.smartphone.name = 'iPhone XR';
    this.smartphone.model = 'Apple';
    this.smartphone.prize = '560';
    this.smartphone.year = '2018';
  }

  ngOnInit() {
  }

}
src/app/modules/application/components/components.component.html
<div class="row">
  <div class="text-center col">
    <h1 class="h3">Features Components</h1>
    <hr>
  </div>
</div>

<div class="row pb-4">
  <div class="text-center col-4">
    smartphone : {{ smartphone | json }}<br>
  </div>
  <div class="text-center col-8">
    <app-smartphone [smartphone]="smartphone"></app-smartphone>
  </div>
</div>
src/app/modules/application/components/smartphone/smartphone.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { SmartphoneComponent } from './smartphone.component';

describe('SmartphoneComponent', () => {
  let component: SmartphoneComponent;
  let fixture: ComponentFixture<SmartphoneComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SmartphoneComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SmartphoneComponent);
    component = fixture.componentInstance;
    component.smartphone = {
      name: 'iPhone XR',
      model: 'Apple',
      prize: '560',
      year: '2018'
    };
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Interpolation with list

Let's modify it to be able to handle a list of components.
src/app/modules/application/components/smartphone/smartphone.component.html
<div class="card">
  <div class="row no-gutters">
    <div class="col-md-6 pt-2 pb-2">
      <img src="./assets/params/images/smartphones/{{ smartphone.name }}.jpg" class="card-img"
        alt="{{ smartphone.name }}">
    </div>
    <div class="col-md-6">
      <div class="card-body">
        <button type="button" class="btn btn-primary btn-sm" (click)="select(smartphone)">n° {{ index }}</button>
        <h6 class="card-subtitle mb-2 text-primary font-weight-bold pt-4">{{ smartphone.name }}</h6>
        <h6 class="card-subtitle mb-2 text-dark">{{ smartphone.model }}</h6>
        <h6 class="card-subtitle mb-2 text-dark">{{ smartphone.prize }}</h6>
        <h6 class="card-subtitle mb-2 text-dark">{{ smartphone.year }}</h6>
      </div>
    </div>
  </div>
src/app/modules/application/components/smartphone/smartphone.component.ts
import { Component, EventEmitter, OnInit, Output, Input } from '@angular/core';

import { Smartphone } from './smartphone';

@Component({
  selector: 'app-smartphone',
  templateUrl: './smartphone.component.html',
  styleUrls: ['./smartphone.component.css']
})
export class SmartphoneComponent implements OnInit {

  @Input() smartphone: Smartphone;
  @Input() index: number;
  @Output() selected: EventEmitter<any> = new EventEmitter<any>();

  constructor() {
  }

  ngOnInit() {
  }

  select(smartphone: Smartphone) {
    this.selected.emit(smartphone);
  }

}
src/app/modules/application/components/components.component.html
<div class="row pb-4">

  <div class="col-12 col-sm-12 col-md-3 col-lg-3 col-xl-3">
    <div class="row p-4">
      <div class="text-center col">
        <h1 class="h5">Feature : Components</h1>
        <hr>
      </div>

      <div *ngIf="!smartphoneSelected">
        <div class="alert alert-primary" role="alert">
          Click on <button type="button" class="btn btn-primary btn-sm">n° x</button>
          <br>to select the smartphone n° x
        </div>
        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Smartphone</h5>
            <h6 class="card-subtitle mb-2 text-muted">Not Selected</h6>
          </div>
        </div>
      </div>

      <div *ngIf="smartphoneSelected">
        <div class="alert alert-info" role="alert">
          Click on <button type="button" class="btn btn-info btn-sm">Reset</button>
          <br>to unselect the smartphone
        </div>
        <div class="card text-center">
          <h5 class="card-title">Smartphone</h5>
          <div class="row no-gutters">
            <div class="col-md-6 pt-2 pb-2">
              <img src="./assets/params/images/smartphones/{{ smartphoneSelected.name }}.jpg" class="card-img"
                alt="name">
            </div>
            <div class="col-md-6">
              <div class="card-body">
                <h6 class="card-subtitle mb-2 text-primary font-weight-bold">{{ smartphoneSelected.name }}</h6>
                <h6 class="card-subtitle mb-2 text-dark">{{ smartphoneSelected.model }}</h6>
                <h6 class="card-subtitle mb-2 text-dark">{{ smartphoneSelected.prize }}</h6>
                <h6 class="card-subtitle mb-2 text-dark">{{ smartphoneSelected.year }}</h6>
                <button type="button" class="btn btn-info btn-sm" (click)="onReset()">Reset</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="col-12 col-sm-12 col-md-9 col-lg-9 col-xl-9">
    <div class="row">
      <div *ngFor="let smartphone of smartphones; let i=index"
        class="col-6 col-sm-6 col-md-4 col-lg-3 col-xl-3 px-2 mb-1">
        <app-smartphone [smartphone]="smartphone" [index]="i + 1" (selected)="onSelected($event)"></app-smartphone>
      </div>
    </div>
  </div>

</div>
src/app/modules/application/components/components.component.ts
import { Component, OnInit } from '@angular/core';

import { Smartphone } from './smartphone/smartphone';

@Component({
  selector: 'app-components',
  templateUrl: './components.component.html',
  styleUrls: ['./components.component.css']
})
export class ComponentsComponent implements OnInit {

  smartphones: Smartphone[];
  smartphoneSelected: Smartphone;

  constructor() {
    this.smartphones =
      [
        { name: 'iPhone 3G', model: 'Apple', prize: '560', year: '2008' },
        { name: 'iPhone 4', model: 'Apple', prize: '560', year: '2010' },
        { name: 'iPhone 5', model: 'Apple', prize: '560', year: '2012' },
        { name: 'iPhone 6', model: 'Apple', prize: '560', year: '2014' },
        { name: 'iPhone 7', model: 'Apple', prize: '560', year: '2016' },
        { name: 'iPhone X', model: 'Apple', prize: '560', year: '2017' },
        { name: 'iPhone XS', model: 'Apple', prize: '560', year: '2018' },
        { name: 'iPhone 8', model: 'Apple', prize: '560', year: '2017' },
        { name: 'iPhone XR', model: 'Apple', prize: '560', year: '2018' },
        { name: 'iPhone 11', model: 'Apple', prize: '560', year: '2019' },
      ];
  }

  ngOnInit() {
  }

  onSelected(event: any) {
    this.smartphoneSelected = event;
  }

  onReset() {
    this.smartphoneSelected = null;
  }

}

Tests

All that remains is to test the different Angular scripts.
# Développement
npm run start
http://localhost:4200/

# Tests
npm run lint
npm run test

# Compilation
npm run build

Code source

The source code used at the beginning of the tutorial is available on github
https://github.com/ganatan/angular-react-bootstrap


The following steps will get you a prototype application.


The following steps will help you improve this prototype​​​​​​​

​​​​​​​
This last step allows you to obtain an example application


The source code for this final application is available on GitHub
https://github.com/ganatan/angular-app

How to create a From scratch application?

Create your ganatan account

Download your complete guides for free

Démarrez avec angular CLI Démarrez avec angular CLI

Gérez le routing Gérez le routing

Appliquez le Lazy loading Appliquez le Lazy loading

Intégrez Bootstrap Intégrez Bootstrap


Utilisez Python avec Angular Utilisez Python avec Angular

Utilisez Django avec Angular Utilisez Django avec Angular

Utilisez Flask avec Angular Utilisez Flask avec Angular

Ganatan site Web avec Angular