🚀Unlocking the Basics of Angular: A Comprehensive Beginner’s Guide for mastering the Fundamentals

Landon Buttars
6 min readFeb 12, 2023

--

Angular logo in front of a laptop and phone

Angular is framework for building complex, dynamic web applications. At its core Angular enables developers to create innovative, scalable, and easy to maintain applications. In this article, we’ll delve into Angular and fundamental concepts that you, as a beginner or an experienced developer, must master to harness the full potential of Angular. We’ll explore the components, services, directives, dependency injection, and good patterns.

Let’s take a closer look at each one:

Components

Components are the most basic building blocks of an Angular application. They represent a piece of the user interface, such as a header, footer, or main content area. Here is an example of a simple component in Angular:

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

@Component({
selector: 'app-header',
template: `
<header>
<nav>
<a routerLink="/home">Home</a>
<a routerLink="/about">About</a>
<a routerLink="/contact">Contact</a>
</nav>
</header>
`
})
export class HeaderComponent { }

In this example, we first import the Component module from the Angular core. Then, we use the `@Component` decorator to define our component. The selector property specifies the name of the component, while the template property specifies the HTML code that should be displayed on the screen.

Services

Services are a way to share data and functionality between components. In Angular, services are responsible for making API calls, handling calculations, managing state, and sharing data.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
providedIn: 'root'
})
export class DataService {

constructor(private http: HttpClient) { }

getData() {
return this.http.get('https://api.example.com/data');
}
}

We first import the Injectable module from the Angular core and the HttpClient module for making API calls. Then, we use the @Injectable decorator to define our service. The providedIn property specifies that this service should be available to the entire application.

Next, we define a constructor that takes the HttpClient as a parameter. This allows us to make API calls from within our service. Finally, we define a getData() method that uses the HttpClient to retrieve data from an API.

Directives

Directives are a way to add custom behavior to a DOM element. They can be used for tasks such as hiding or showing elements, adding styles, or adding event listeners. Here is an example of a simple directive in Angular:

import { Directive, ElementRef, Renderer2 } from '@angular/core';

@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {

constructor(private el: ElementRef, private renderer: Renderer2) {
this.renderer.setStyle(this.el.nativeElement, 'background-color', 'yellow');
}
}

In this example, we first import the Directive, ElementRef, and Renderer2 modules from the Angular core. Then, we use the `@Directive` decorator to define our directive. The selector property specifies the name of the directive, which can be used in HTML to apply the custom behavior.

Next, we define a constructor that takes the ElementRef and Renderer2 as parameters. The ElementRef allows us to access the DOM element that the directive is attached to, while the Renderer2 allows us to manipulate the DOM element.

In this example, we use the renderer to set the background color of the DOM element to yellow. By doing this, whenever this directive is applied to an element, it will turn yellow.

Dependency Injection

Dependency injection is a powerful feature of Angular that allows components and services to access shared data stored in services without having to create them directly. This makes it easier to write modular, reusable code and to test individual pieces of your application. Here is an example of a component that uses a service with dependency injection:

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
selector: 'app-home',
template: `
<h2>Home Page</h2>
<p>{{ data }}</p>
`
})
export class HomeComponent {

data: any;

constructor(private dataService: DataService) {
this.data = this.dataService.getData();
}
}

In this example, we import the Component module from the Angular core and the DataService from our component. Then, we use the `@Component` decorator to define our component. The selector property and template property are similar to our previous component example.

Next, we define a constructor that takes the DataService as a parameter. By doing this, we can use the DataService within our component without having to create it directly. In this example, we use the getData() method from our DataService to retrieve data and display it on the screen.

Good Patterns:

Presentation vs Container Components

The container vs presentation component pattern in Angular refers to the division of responsibilities between two types of components: presentation components and container components.

A presentation component is focused on the visual representation of data and is responsible for displaying information to the user. It typically receives data through inputs and is often stateless.

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

@Component({
selector: 'app-display-data',
template: `
<p>{{ data }}</p>
`
})
export class DisplayDataComponent {
@Input() data: any;
}

A container component, on the other hand, is concerned with managing the data and state of the application. It provides the data to the presentation component through outputs and is often stateful.

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

@Component({
selector: 'app-container',
template: `
<app-display-data [data]="data"></app-display-data>
`
})
export class ContainerComponent implements OnInit {
data = '';

constructor(private dataService: DataService) {
}

ngOnInit {
this.data = this.dataService.getData();
}
}

In this example, the ContainerComponent is responsible for fetching managing the data and state of the application and providing it to the DisplayDataComponent through the data input. The DisplayDataComponent only focuses on the visual representation of the data and displays it to the user. This pattern allows for better separation of concerns and makes the application easier to maintain and test. Additionally, container components are responsible for fetching data from services to provide to presentation components.

By dividing the responsibilities of an Angular application into presentation and container components, it becomes easier to maintain and test. This is because each component has a clear and single responsibility, reducing the risk of tightly coupled and complex code. This pattern also promotes modularity, making it easier to understand and develop the application as a whole.

In summary, the container vs presentation component pattern in Angular is a helpful way of structuring an application by separating the responsibilities of components and promoting modularity, maintainability and testability.

Separation of Responsibility Using Services

In Angular, the distinction between a service and a component is determined by the code’s responsibilities. Services serve as the arbiters of shared, component-independent data and state management, performing duties such as API calls, data transformation management, and inter-component data sharing.

Conversely, components embody the visual representation of data and dictate how information is displayed to the user. Additionally, components handle user interactions, such as form submissions and button clicks, and are equipped with the logic necessary for manipulating data supplied by services.

In essence, code that manages shared, component-agnostic data and state belongs in a service, while code responsible for visual representation and user interaction belongs in a component. This stark division of responsibilities provides clarity in terms of separation of concerns and facilitates easier maintenance and testing of the application.

An example of the DataService used in the previous example might look like this.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) {}

getData() {
return this.http.get('https://api.example.com/');
}
}

Conclusion

Angular is a powerful framework that offers a wide range of features for building dynamic and interactive web applications. By understanding components, services, directives, dependency injection, and a few good patterns, you’ll be on your way to becoming an Angular expert.

If you found this introduction into Angular please leave me a few claps. It really helps me out!

Happy coding!

Written By: Landon Buttars

--

--

Landon Buttars

Full-Stack Developer specializing in Angular, Node.js, AWS, and Nx. Passionate about creating efficient, scalable, and user-friendly web applications.