From PHP to Angular!
This post aims to be a partial answer to the question "what is Angular?" for me: a php developer that would come back to the front side of the web.
Install globally
Global versus local installation
For those who came from php, I'm going to introduce the package manager used in nodejs world. In the PHP world, developers uses a tool called composer. Whenever is necessary the installation of a library in node application, the equivalent tool is called npm.
npm
stands for Node Package Manager. In npm things can be installed globally or locally. The former install packages in the current working directory and executable in {prefix}/bin. The latter USES {prefix}/lib/ and {prefix}/.bin instead.
If you need a manual to better understand the module usages remember that the local installation does not include the man pages.
npm
is still maintained. Remember to runnpm install -g npm
to be sure your version is up to date
Global installation
For this post I'll use CLI global installation. Angular cli stands for Angular Command Line Interface: cli. Is the Angular tool to create application from command line. It provides basic boilerplates for your applications. To install a package the required instruction is npm install “packageName”
. To install the package globally the -g
option is required.
npm install @angular/cli
npm install -g @angular/cli
Installing a package globally allows you to use the code in the package as a set of tools on your local computer. In advance, provide the documentation as said in the previous chapter.
Create new project
Angular cli enables ng
command. We will use it to create our projects. Running the following command few question are made to the developer. Suggested step are written in the following paragraphs. So, ... let's create new project.
ng new <projectName>
The application creation process is guided. You will go through a set of questions that will help you to configure your app. For simplicity we resume some options: say ‘yes’ to the question related to angular routing, and select scss
when styles tolls is requested.
Let's open the project in your favorite browser
The following command allows you to see what we've made so far. Yes we did nothing yet but as said before ng
did something for us. To see the result just run the following command.
ng serve -o
Entry point
Introduction
The entry point is the file where the application starts. This is the file that will be loaded first and aims to load all modules and provide all the application specific business logic.
/index.html
The entry point of our applications is the index.html file. As said before, ng
command is a boilerplate and by default it provide an app component. This file is created by ng
. So, thank you ng
.
A component decorator provides selector as the target of html page, templateUrl as the template file and styles as the path of scss
files related to this component.
In angular a decorator is made with a particular syntax: a word with @
as prefix (@DecoratorName({})
). For example @Component({}) is a decorator for our component.
App default component
ng new …
creates components. Let's have a look at the code and after that we will start to learn about important concepts such as "selector", "templateUrl" and "styleUrls"
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
As said in the previous paragraph, it indicates the selector where the component will be rendered on app-root
component. The template file is './app.component.html' that means that in the folder /src/app/
folder there will be a file html used specifically for this component. And finally the styleUrls witch provides the list of scss files to style the component.
Global scss
In an angular application there are different scss files. Each component has its own file. There is also a scss file for the whole application and it is stored in /src/styles.scss
. Any common style rules are provided here.
Create components
Each component, such as navigation, menu, and others … can be created using the command generate
. There is a full syntax ng generate component nav
(to create nav component) but also a short one ng g c nav
. The g
stands for generate and the c
stands for component. The command will generate the necessary files: templates, scss and so on.
Navigate the app with others components
Adding and viewing additional components in the application is very easy stuff to do. First of all we have generated a component. The nav component. We can generate others using again g c
(generate component) command again and again. We have created a nav menu to navigate the application. Te template part of the nav component. Now it should contain something like the following template. Pay attention to the routerLink attribute. It indicates the path we will configure in routing module.
<div class="nav">
<h1>Application</h1>
<ul>
<li><a routerLink="/">home</a></li>
<li><a routerLink="/resources">resources</a></li>
</ul>
</div>
Where all paths must be defined? All paths are defined in the /src/app/app-routing.module.ts
file. It should contains the import of each component and also an item of the routes array.
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ResourcesComponent } from './resources/resources.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'resources', component: ResourcesComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Angular modules are a cohesive group of code which are integrated with the other modules to run your Angular apps. A module can exports some classes, functions and values from its code. The Component is a fundamental block of Angular and multiple components will make up your application.
Interpolation
The angular compiler, during the compilation process, looks for if text nodes and element attributes that contain markup with embedded expressions (called interpolation). For each of these expressions, the compiler adds an interpolation directive to the node and registers listeners on the computed interpolation function, which will update the corresponding text nodes or attribute values as part of the normal digest cycle.
In the following practical case we indicate a property name using curly braces and set the value using a component property.
{{ propertyName }}
To set the value of a property is enough to set the value of the property of the same component.
Import { Component, OnInit } from ‘@angular/core’;
export class MyComponent implements OnInit {
propertyName: string = ‘the property value ’;
constructor() { }
ngOnInit() { }
}
Listen for events
In classical HTML to handle events such as onClick
we use an attribute with the same name. For example:
<button onClick=“handlerFunction()”>Click me</button>
In the angular way it is used a different syntax.
<h1>Home</h1>
<button (click)=>”firstClick()”>Click me</button>
The function called in html part must be a method of the corrispettive component class. The same where a component defines properties. For simplicity I will omit the not interesting part of the component.
export class MyComponent {
firstClick() {
console.log(‘clicked’)
}
}
About styles
A very interesting feature I’ve learned about Angular is the way you can add a style to an item. In the following example a certain class is added to the element if a certain condition in quotes is verified. Literally, … the class grey is added to the h1 element whenever the property of h1Style of the component is true.
<h1 [class.grey]=“h1Style”>Home</h1>
An easy way to read the previous code is
<htmlTag [apply this style]="if this condition is true">xxx</htmlTag>
The following is the typescript side of the code. The h1Style property is false by default and this means that the h1 node will not have grey class. In previous paragraphs we handled events. In that events we can toggle the value of h1Style property and add grey class to h1 element.
export class MyComponent implements OnInit {
h1Style: boolean = false;
firstClick() {
this.h1Style = true;
}
}
Last but not least the css part with the definition of grey class.
.grey {
color: gray;
}
With these scss, typescript and html we have a simple application with an h1 element that become gray after a click. Let's see other ways to style our application with angular in following paragraphs.
ngClass for multiple classes
Here the way to handle with a complex classes assignment. The following is a pseudo-code way to consider ngClass
:
<htmlTag [ngClass]="
'apply this class': 'if this condition is true'
">xxx</htmlTag>
And now a real example. Literally
- apply grey class if h1Style is true
- apply also large class if h1Style is false
<h1 [ngClass]=“{
‘grey’: h1Style,
‘large’: !h1Style,
}”>Home</h1>
Here the full stylesheet with both grey and large style.
.gray {
color: gray;
}
.large {
font-size: 4em;
}
css properties
Here an example that aims to apply a single color to a tag. Like in previous examples fist I'll illustrate the pseudocode and then the real code.
<htmlTag [apply font-color style]="
typescript code that return the color
">xxx</htmlTag>
Here the real code. Literally whenever h1Style property is true is applied the gray
color, brack
conversely.
<h1 [style.color]=“h1Style ? ‘gray’ : ‘black’”>Home</h1>
Multiple css properties
Like classes, also single styles can be applied simultaneously.
<h1 [ngStyle]=“{
‘color’ : h1Style ? ‘gray’ : ‘black’,
‘font-size’ : !h1Style ? ‘1em’ : ‘4em’,
}”>Home</h1>
Services
Create a service using ng
is very very simple. As seen before about component creation we will use ng generate
command. In this example we will create a service that provides data to the application.
ng g s data
Let's see few stuff. First of all this component import Injectable decorator from the angular core library. We have seen decorators at the beginning of current post. The service is a singleton. One way to create a singleton service in angular is to "Declare root for the value of the @Injectable() providedIn property". Another way is to "Include the service in the AppModule or in a module that is only imported by the AppModule".
import { Injectable } from ‘@angular/core’;
@Injectable({
providedIn: ‘root’
})
export class DataService {
constructor() { }
firstClick() {
return console.log(‘clicked’);
}
}
The service can be declared as private inside the component.
import { Component, OnInit } from ‘@angular/core’;
import { DataService } from ‘../data.service’;
export class MyComponent implements OnInit {
constructor(private data: DataService) { }
firstClick() {
this.data.firstClick();
}
}
Http client module
To make more challenging the post, instead of just log "clicked" in the console the service may provide some data. For example the list of users of current application. We could suppose to get users from an external api. In this case we introduce an angular module for http calls.
import { Injectable } from ‘@angular/core’;
import { HttpClient } from ‘@angular/common/http’;
@Injectable({
providedIn: ‘root’
})
export class DataService {
constructor(provate http: HttpClient) { }
getUsers() {
return this.http.get(‘https://fo/bar’);
}
firstClick() {
return console.log(‘clicked’);
}
}
After the import, we just need to get data from a particular url. The following code omit other parts of code and keep just the necessary for http calls concepts.
import { Component, OnInit } from ‘@angular/core’;
import { DataService } from ‘../data.service’;
export class MyComponent implements OnInit {
users: Object;
constructor(private data: DataService) { }
ngOnInit() {
this.data.getUsers().subscribe(data => {
this.users = data;
console.log(this.data);
});
}
}
Given the list of users from the api, retrieved using http client, now we could rendere everything manipulating the html parts like this snipped of template.
<ul *ngIf=“users”>
<li *ngFor=“let user of users.data”>
<img [src]=“users.avatar”>
<p> { { user.first_name }} { { user.last_name }}</p>
</li>
</ul>
Finally to add a little style to the list, we must define the css part. Here a suggested scss part.
ul {
list-style-type: none;
li {
background: gray;
p {
font-weight: bold;
}
}
}
Forms
The penultimate topic is form. Forms may be loaded as modules with the following import and NgModules configuration.
import { ReactiveFormsModule } from ‘@angular/forms’;
@NgModules({
imports: [
ReactiveFormsModule
]
})
Following snippets are the typescript and the html parts.
import { Component, OnInit } from ‘@angular/core’;
import { FormBuilder, FormGroup, Validators } from ‘@angular/forms’;
@Component({
selector: ‘app-component’,
templateUrl: ‘./contact.component.html’,
styleUrls: [‘./contact.component.scss’]
})
export class ContactComponent implements OnInit {
messageForm: FormGroup;
submitted: false;
success: false;
constructor(private formBuilder: FormBuilder) {
this.messageForm = this.formBuilder.group({
name: [‘’, Validators.required],
message: [‘’, Validators.required],
});
}
onSubmit() {
this.submitted = true;
if (this.messageForm.invalid) {
return;
}
this.success = true;
}
ngOnInit() { }
}
<h1>Contact</h1>
<form [formGroup]=“messageForm” (ngSubmit)=“onSubmit()”>
<h5 *ngIf=“success”>your form is valid</h5>
<label>Name: <input type=“text” formControlName>
<div *ngIf=“submitted && messageForm.controlname.errors” class=“error”>
<div *ngIf=“messageForm.controls.name.errors.required”>Your name is required</div>
</div>
</label>
<input type=“submit” value=“Send” />
</form>
<div *ngIf=“submitted” class=“results”>
<strong>Name</strong>
<span>{{ messageForm.controls.name.value }}</span>
</div>
Deploy
Last but not least, deploy process. The ng command offers also a build command. Follow following steps.
ng build
ng build —prod
cd projectName
http-server -o
And now open http://127.0.0.1:8080
Top comments (0)