Note that I am still a backend developer who is dealing with frontend stuff BTW it is not so hard. IMO Angular is much better that Vue and React. TBH I felt unsettled about the part that we use data in our templates and pass them between our components but soon I found this extension
and life was so much easier.
Angular
- It is test friendly
- It comes with a lot of things. I do not need to deal with tedium tasks. Obviously a little bigger.
- Use TS by default. Hooray
- Has RxJS in place. TBH I still had no time to learn it deeply
Angular components
- We can see them as a patch of screen which is called view.
- It is an customized Angular directive - Extends @Directive
- Template/HTML + Component/class = View
- Reusable components
- Embed them in each other. You do not need to import components in each other you just need to know the component's selector name.
- We can implement OnInit to do things which should be done when project get initialized.
- Angular update/create/destroys components based on user movements between components. Therefore if you need to do something during those phase changes you can use Angular lifecycle hooks
.
- Create new components with this command, please note that I like to follow NestJS structure here too. So I do put all components, services, and related stuff in a directory.
ng generate component name
@Component decorator
- selector: string, the html tag that you wanna put this component inside it. It always should be app-*
- templateUrl: string, html file which is associated with this component
- styleUrls: string[], this component css files
- providers: If you inject a file in the component's class you have to put it in the providers
- The annotated class with this decorator held app logic. This class interact with view via its public properties/methods.
@Input decorator
- Pass data from parent component to the child component easily, unlike Vue or React where passing arguments are a pain in ass IMO
<app-name dataName="value"></app-name>
<app-name [dataName]="value"></app-name>
@Output decorator
- Pass event - When a button has been clicked - from child component to the parent component easily, unlike Vue or React where passing arguments are a pain in ass IMO
<app-name eventName="methodName"></app-name>
<app-name (eventName)="methodName"></app-name>
templates
- They are html files generally
- Bind data from component's class to view
Inside the templates we can use string interpolation. It is basically very close to what we were doing in handlebars as far as I can say.
- Pipes: Transform data before displaying it. We have built-in pipes, and also we can create our custom pipes. The really interesting part is that we can chain them together as we done it many times in bash.
Angular services
- Separate concerns
- Have neat components by putting validation and other stuff in service layer
- Modular codebase
Angular CLI
This is the most fascinating thing about Angular. I do not need to create boilerplate and write repetitive common code. I just use Angular CLI as I use NestJS CLI.
angular.json
- Config file for our angular app
- Specify CDNs
- Specify the build directory
- Specify Assets to be copied to the built version as we have in NestJS
- Specify CSSs
App
Main module which we have and is responsible to get all other modules. It is annotated with @NgModule decorator. Basically every module should be annotated with this decorator. Anyway, we have 3 major option in the @NgModule decorator:
- imports: Other modules, where they can be built-in modules - such as FormsModule - or your own module.
- declarations: module's components
- bootstrap: specify main entrypoint component in this option.
main.ts
- Entry point of our app where is responsible to bootstrap our app and do global configurations
Angular Directives
- Basically directives gave instruction to Angular to change DOM as they wanted to see it.
- Directives extend the power of HTML
- Directives are classes which add additional behavior to elements
- We have built-in directives to manage forms, lists, styles, and basically everything that users see.
We have 3 directive type:
Roughly speaking or AFAIK [] in templates is used for inputs and () is used for outputs. And we have a two way binding which is [()].
ngStyle
ngSubmit
- Interfere with default behavior of submit button. It is amount to e.preventDefault()
- You must specify a method inside the component's class
Angular specific elements
ng-container
- It holds structural directives without adding new elements to the DOM. Assume you do not wanna add new element to your DOM unless a specific condition met.
Forms - Validation and other stuff - in Angular
- For validation we have built-in validators, custom validators, async validators which respond to the user activities.
- We can create our forms in two ways either template - HTML files - driven, or model - Component class - driven
Template driven
- Do you need to be super fast in development? use template driven
- No validation, Obviously you can do basic validations in HTML but you cannot do advance validations.
- You will use ngModel and ngSubmit
- You do not need to introduce your form to Angular. It is already known.
- #formName
="ngForm" ngSubmit="onSubmit(formName.value)"
Model driven
- Full power but a little more work
- Advance validation
- Change tracking
- Simpler unit test
- Needs ReactiveFormsModule
Router
- To do routing in Angular you need <head><base href="/" /></head> in the index.html
- It performs a client side routing for us
In SPA - Single Page Application - you wanna show/hide portion of the display rather than sending a HTTP request and asking for new page.
- Works based on browser URL; It takes URL as instructions to change DOM
- You need to define a 404 page by using wild cards
- Keep in mind that here as we had in ExpressJS/React the order of routes matters. So please follow this rule: First more specific routes then more common.
- Based on my experiences in ExpressJS I hate to separate things from each other. Therefore I did this: create a new file besides the component and do this inside it:
- routerLink is the attribute we use to specify which component's view should be shown.
- router-outlet tag tells Angular to update DOM based on link
- I personally decided to create a new file in each module - remember I said I put related things in a directory and I won't separate things. So I create a file in each module - module-name-routes.ts and coppy this things in it:
import { Routes } from '@angular/router';
import { LoginComponent } from './login.component';
export const routes: Routes = [
??component: LoginComponent,
Config your routes
- title: It specify title of the page
- path: It specify the path that should be matched with url. Its default value is /. Note: do not use this config in unison matcher.
- pathMatch: Accept two value: "prefix" and "full". Use full when you're using redirectTo config to prevent infinite redirect. Angular matches url from left to right and this is why we said order matters, I mean Angular on the first match returns and do not look at other routes.
- matcher: A custom function which is an alternative for path. Do not use this config in unison with path.
- component: Specify the responsible component, Angular will instantiate from it. It can be missed if children is specified.
- loadComponent: To do lazy-load component
- redirectTo: Specify the path where Angular should redirect. Note: make sure you specify pathMatch: "full".