Angular — Basic to Advance — Every Concept Explained! — part 1

Rushabh Dabhade
13 min readSep 4, 2023

In the rapidly evolving landscape of web development, Angular has emerged as a powerful and versatile framework that empowers developers to build dynamic, feature-rich, and responsive web applications.Angular, developed and maintained by Google, has gained widespread adoption for its ability to create single-page applications with ease. From its foundational architecture to its advanced features, this blog series aims to demystify every aspect of Angular, breaking down complex concepts into digestible explanations that cater to developers of all skill levels.

Files and Folder Structure

In Angular, the files and folder structure are designed to provide a logical organization for your project’s source code, making it easier to manage and develop your application. Here’s a brief overview of the typical files and folders you’ll encounter in an Angular project:

  1. src: This is the main directory where your application’s source code resides. It contains most of the code you’ll be working with.
  • app: This is where your application’s components, services, modules, and other related files are stored. It’s the heart of your application.
  • components: Contains individual component folders, each with its TypeScript, HTML, CSS, and potentially other files.
  • services: Holds service files that provide functionality shared across components.
  • modules: Contains Angular module files that help organize and configure your application.
  • assets: This is where static assets like images, fonts, and other files are stored. These assets can be accessed directly by your application.
  • styles: Contains global styles, such as CSS or SCSS files, that are applied across the entire application.
  • index.html: The main HTML file that serves as the entry point for your application.

2. angular.json: This configuration file defines various settings for your Angular project, including build options, asset paths, and other project-specific configurations.

Here's a brief explanation of the key aspects of the angular.json file:

  1. projects: This section contains configurations for one or more projects within your Angular workspace. Each project represents an application, library, or other related code within your workspace.
  • architect: This subsection defines the various build, test, and serve tasks you can run on your project.
  • build: Configures options for building your project for production or development. You can specify the output paths, assets, styles, scripts, and more.
  • test: Configures testing settings using testing frameworks like Karma or Protractor.
  • serve: Configures the development server settings for serving your application locally during development.
  • lint: Configures linting options for checking your code against coding standards.
  • e2e: Configures end-to-end (e2e) testing settings for running tests that simulate user interactions.

2. schematics: This section allows you to define custom schematics or use third-party schematics to generate code and files for your project.

3. cli: Contains settings related to the Angular CLI itself.

  • defaultCollection: Specifies the default collection of schematics that the CLI should use when generating code.

4. newProjectRoot: Defines the root directory for new projects created within your workspace.

5. sourceRoot: Specifies the root directory where your application’s source code resides.

6. prefix: Defines the prefix that is automatically added to the selectors of components, directives, and other Angular elements generated within your project.

7. targets: Within each project’s “architect” section, you’ll find “targets” that represent specific tasks. These targets can be invoked using the Angular CLI.

  • builder: Specifies the builder (tool) that is responsible for carrying out the task.
  • options: Contains options specific to the task.
  • configurations: Defines different configurations for the target, such as “production” or “development” settings for the “build” task.

3. tsconfig.json: This file configures TypeScript compiler options for your project.

4. package.json: This file holds information about your project’s dependencies and scripts. It’s used by npm (Node Package Manager) to manage packages and scripts.

Here's a breakdown of what the package.json file includes:

  1. name: This field specifies the name of your project. It's a unique identifier and should follow naming conventions.
  2. version: The version of your project. This is important for tracking changes and managing updates.
  3. scripts: This is a key section where you define custom scripts that can be run using the command line. Common scripts in Angular projects include:
  • start: Used to start the development server.
  • build: Used to build your application for production.
  • test: Used to run tests.
  • lint: Used to run code linting.
  • Custom scripts you might define to automate various tasks.

4. dependencies: This lists the packages that your project depends on to function correctly. These packages are required for your application to run in production.

5. devDependencies: Similar to dependencies, but these packages are only needed during development and not in the final production build.

Interpolation

Interpolation is a fundamental concept in Angular’s template syntax that allows you to dynamically display data values from your component’s TypeScript code within your HTML templates. It’s a way to seamlessly combine the logic and data manipulation from your component with the user interface in your template. Interpolation is denoted by double curly braces {{ }} in your template.

Example in an Angular component and template:

Component (app.component.ts):

export class AppComponent {
greeting: string = 'Hello, Angular!';
count: number = 42;

getDynamicValue(): string {
return 'Dynamic Value';
}
}

Template (app.component.html):

<h1>{{ greeting }}</h1>
<p>The answer to everything is {{ count }}</p>
<p>This is a {{ getDynamicValue() }}</p>

In this example, the values of greeting, count, and the result of the getDynamicValue() function are dynamically inserted into the HTML using interpolation. As the values change in the component, the template will automatically update to reflect those changes.

Angular CLI & Important Commands

The Angular CLI (Command Line Interface) is a powerful tool provided by the Angular team to streamline the development, testing, and deployment of Angular applications. It offers a set of commands that simplify various tasks associated with Angular project management, development, and maintenance.

To use the Angular CLI, you need to have Node.js and npm (Node Package Manager) installed on your system. You can install the Angular CLI globally using the following npm command:

npm install -g @angular/cli

Once installed, you can create, develop, test, and deploy Angular applications efficiently using the various commands provided by the CLI.

Components

A component is a fundamental building block of your application’s user interface. It represents a specific section of your user interface that encapsulates both the visual representation (HTML template) and the logic (Typescript class) associated with that section.

Generate the Component: Use the Angular CLI’s g c command to create a new component. The general syntax is:

ng g c component-name

Replace component-name with the desired name of your component in kebab-case (all lowercase with hyphens).

Here’s a breakdown of the common files you’ll find within an Angular component directory:

  1. Component Class (Typescript):
  • component-name.component.ts: This TypeScript file contains the class that defines the behavior and logic of the component. It includes properties, methods, event handlers, lifecycle hooks, and any other logic related to the component.

2. Template (HTML):

  • component-name.component.html: This HTML file defines the structure and content of the component's user interface. It can include HTML elements, data bindings, directives, and placeholders for dynamic content.

3. Styles (CSS or SCSS):

  • component-name.component.css: This CSS file contains styles specific to the component. You can use regular CSS styles here.
  • component-name.component.scss: Alternatively, you can use SCSS (Sass) styles if you prefer a more powerful and modular way of writing styles.

4. Test File (Optional):

  • component-name.component.spec.ts: This TypeScript file contains unit tests for the component. You can use testing frameworks like Jasmine and tools like Karma to write and run tests to ensure your component behaves as expected.

Component with Inline Style

Creating an Angular component with inline styles involves defining the component’s styles directly within the component’s TypeScript file using the styles property in the @Component() decorator. This approach can be useful for adding simple and specific styles that are closely related to the component's template.

Run the command

ng g c component-name --inline-style

Edit the Component TypeScript File (component-name.component.ts): Open the component's TypeScript file and update the @Component() decorator to include the styles property. The styles property should be an array of strings, where each string contains the CSS rules for the component's styles.

Here’s an example:

import { Component } from '@angular/core';

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styles: [
`
.my-component-container {
background-color: lightblue;
padding: 20px;
}
`,
`
h2 {
color: red;
}
`
]
})
export class MyComponent { }

Modules

In Angular, a module is a mechanism for organizing related components, services, directives, and other code into cohesive units. Modules help to modularize your application and promote separation of concerns by grouping functionalities together. Angular applications are built by combining multiple modules, each responsible for a specific part of the application.

Generate the Module: Use the Angular CLI’s generate module command to create a new module. The general syntax is:

ng generate module module-name

Replace module-name with the desired name of your module in kebab-case (all lowercase with hyphens).

Here’s a simple example of creating an Angular module:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

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

Make and Call Function

Functions, often referred to as methods, are defined within components and services to encapsulate logic, handle events, perform calculations, and interact with data.

import { Component } from '@angular/core';

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent {
counter: number = 0;

incrementCounter() {
this.counter++;
}
}
<button (click)="incrementCounter()">Increment Counter</button>

Events

In Angular, events refer to interactions or occurrences that happen within the user interface of your application. These interactions can include actions like clicks, key presses, mouse movements, input changes, and more. Angular provides mechanisms to handle these events and respond to them in order to create dynamic and interactive user experiences. Here are the key aspects of events in Angular:

  1. Event Binding: Event binding is a way to listen for and respond to events triggered by user interactions. It involves binding a method from your component’s class to an event in the template using the (event) syntax.
<button (click)="handleClick()">Click Me</button> 
<input (input)="handleChange($event)">

2. Event Objects: When an event is triggered, an event object is passed to the event handler method. This object contains information about the event, such as the type of event, target element, and more.

handleClick(event: MouseEvent) {
console.log(`Button clicked! Event type: ${event.type}`);
}
handleChange(event: Event) {
const inputValue = (event.target as HTMLInputElement).value;
console.log(`Input value changed: ${inputValue}`);
}

3. Event Types: Different types of events correspond to different user interactions. Common event types include click, input, change, mouseenter, mouseleave, keydown, keyup, and more.

4. Event Modifiers: Angular provides event modifiers that allow you to modify the behavior of events. For example, you can use the (click) event with the stopPropagation modifier to prevent event propagation.

<button (click.stop)="handleClick()">Click Me</button>

5. Two-Way Data Binding: Angular supports two-way data binding using the [(ngModel)] directive. This allows you to bind both data property and event handling together for input elements, keeping the view and model synchronized.

<input [(ngModel)]="username">

6. Custom Events: You can also create and emit custom events using Angular’s EventEmitter. This is particularly useful when you need to communicate between parent and child components.

import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: '<button (click)="emitCustomEvent()">Emit Event</button>' })
export class ChildComponent {
@Output() customEvent = new EventEmitter<void>();
emitCustomEvent() {
this.customEvent.emit();
} }
<app-child (customEvent)="handleCustomEvent()"></app-child>

By binding to events and handling them in your component’s methods, you can enable users to interact with your application and trigger various actions and behaviors.

Property Binding

Property binding is a fundamental concept in Angular that allows you to set and update the properties or attributes of HTML elements and Angular directives dynamically. With property binding, you can bind the property of an HTML element or an Angular directive to an expression or a value defined in your component’s TypeScript code. This enables you to create dynamic and data-driven user interfaces.

Here are the key points to understand about property binding in Angular:

Binding Syntax: Property binding is achieved using square brackets [] in the template. You place the property you want to bind within the square brackets, followed by an equal sign and an expression or value you want to bind it to.

<!-- Example of binding the "src" property of an image element -->
<img [src]="imageUrl">

Binding to Component Properties: In most cases, you bind properties to values or expressions defined in your component’s TypeScript code. This allows you to dynamically update the property based on the component’s data.

export class MyComponent {
imageUrl = 'path/to/default-image.jpg';
}

Property Binding with Angular Directives: Property binding is commonly used with Angular directives. For example, you can bind properties of built-in directives like ngStyle, ngClass, or ngIf, as well as custom directives.

<div [ngStyle]="{ 'font-size.px': fontSize }">Dynamic Font Size</div>
<button [disabled]="isDisabled">Click Me</button>

Binding to DOM Properties: You can bind to standard HTML element properties like src, href, disabled, value, innerText, and many more. Additionally, you can bind to custom properties defined in your custom Angular components.

One-way Binding: Property binding is a form of one-way binding. It sets the property in the DOM element or directive based on the component’s data, but changes in the DOM element do not affect the component’s data

If-Else

In Angular templates, you can use structural directives to create conditional rendering based on if-else conditions. The primary directive for this purpose is *ngIf, which allows you to conditionally render or remove elements from the DOM based on the evaluation of an expression. You can also use the else keyword in combination with *ngIf to implement an if-else structure. Here's how to use if-else conditions in Angular templates:

<div *ngIf="condition; else elseBlock">
<!-- Content to display if the condition is true -->
</div>
<ng-template #elseBlock>
<!-- Content to display if the condition is false -->
</ng-template>

In this example:

  • condition is a boolean expression in your component's TypeScript code.
  • If condition is true, the content within the *ngIf block is displayed.
  • If condition is false, the content within the elseBlock template is displayed.

Ternary Operator in Template: For simple if-else conditions, you can also use the ternary operator (? :) directly in the template to conditionally render content:

<div>
{{ condition ? 'This is shown if condition is true.' : 'This is shown if condition is false.' }}
</div>

For multiple if-else conditions:

<ng-template [ngIf]="color==='red">
<h1>Red Color</h1>
<ng-template>

<ng-template [ngIf]="color==='green">
<h1>Green Color</h1>
<ng-template>

<ng-template [ngIf]="color==='blue">
<h1>Blue Color</h1>
<ng-template>

Switch case

In Angular templates, you can implement switch-case logic using the ngSwitch directive and ngSwitchCase or ngSwitchDefault to conditionally render content based on the value of an expression.

<div [ngSwitch]="selectedOption">
<p *ngSwitchCase="'option1'">Option 1 is selected.</p>
<p *ngSwitchCase="'option2'">Option 2 is selected.</p>
<p *ngSwitchCase="'option3'">Option 3 is selected.</p>
<p *ngSwitchDefault>No option is selected.</p>
</div>

In this example:

  • selectedOption is a property in your component's TypeScript code that contains the selected option.
  • The [ngSwitch] directive is used to specify the expression to be evaluated.
  • Each *ngSwitchCase block checks for a specific value of selectedOption and displays content accordingly.
  • The *ngSwitchDefault block is used as a default case when none of the ngSwitchCase conditions match.

Here’s a simple example of how you might define the selectedOption property in your component's TypeScript code:

import { Component } from '@angular/core';

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent {
selectedOption: string = 'option1'; // Initially set to option1
}

For loop

In Angular templates, you can use the *ngFor directive to create loops and iterate over collections like arrays or lists. This directive allows you to render elements for each item in the collection.

<ul>
<li *ngFor="let item of items">
{{ item }}
</li>
</ul>

In this example:

  • items is an array or iterable collection in your component's TypeScript code.
  • The *ngFor directive is applied to the li element.
  • let item of items defines the loop, where item is a template variable that represents each item in the items collection.
  • let i = index defines an optional template variable i to access the index of the current item.

This code will render an ordered list (ul) with list items (li) for each item in the items array. The i + 1 expression is used to display the item's index (1-based) along with its value.

Here’s an example of how you might define the items property in your component's TypeScript code:

import { Component } from '@angular/core';

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent {
items: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
}

Nested loop

You can create nested loops in Angular templates by using multiple *ngFor directives within each other. This allows you to iterate over nested collections, such as arrays of arrays or arrays of objects containing arrays. Here's an example of how to create a nested loop in an Angular component's template:

import { Component } from '@angular/core';

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent {
nestedArray: number[][] = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
}

In your template, you can use nested *ngFor loops to iterate over this data structure:

<table>
<tr *ngFor="let row of nestedArray">
<td *ngFor="let cell of row">
{{ cell }}
</td>
</tr>
</table>

In this example:

  • The outer *ngFor loop iterates over each row in the nestedArray.
  • The inner *ngFor loop iterates over each cell within the current row.
  • cell represents each value within the nested arrays, and it is displayed in a table cell (<td>).

This code will render a table where each row contains values from the nestedArray, demonstrating a basic example of a nested loop.

In this article, we’ve taken our first steps into the exciting world of Angular, exploring fundamental concepts that serve as the foundation for building dynamic and robust web applications. We’ve delved into the essential concepts of Angular, from understanding its file and folder structure to exploring modules, components, interpolation, and property binding. Additionally, we’ve learned how to implement conditional rendering with *ngIf and even how to create loops using *ngFor.

As we wrap up part one of our journey through Angular, we’ve gained a strong grasp of these core concepts, setting a solid foundation for more advanced topics and techniques in part two. In the upcoming segments, we’ll dive deeper into Angular’s powerful features, exploring services, routing, forms, HTTP interactions, and so much more.

So, stay tuned! Part two of our Angular exploration promises to be an exciting continuation of our learning journey, where we’ll uncover the tools and techniques that will empower you to build modern, interactive web applications with ease. Until then, keep exploring and practicing what you’ve learned so far, as it’s the best way to solidify your understanding of Angular and pave the way for your development expertise to flourish.

--

--

Rushabh Dabhade

Full Stack Developer | Building Beautiful Apps | Freelancer | Exploring the world of tech