Awesome
Learning Angular (not AngularJS)
Just one of the things I'm learning. https://github.com/hchiam/learning and https://github.com/hchiam/learning-frameworks
Angular comes with a CLI and comes with TypeScript.
https://angular.io/guide/what-is-angular
Minimal setup from scratch
<details> <summary>Click to expand/collapse:</summary>Using Angular CLI:
npm install -g @angular/cli
# to start a new project "my-app" from scratch:
ng new my-app
cd my-app
ng serve
Or triple-click to select this one-liner:
npm install -g @angular/cli && ng new my-app && cd my-app && ng serve
</details>
Intro
<details> <summary>Click to expand/collapse:</summary>Tutorial I'll be following: https://angular.io/start
https://stackblitz.com/angular/anddyavxapb?file=src%2Fapp%2Fapp.component.ts
cd angular-fhxvfx
yarn
# yarn build
yarn start # runs ng serve
-
Structural directive examples:
*ngFor="let product of products"
and*ngIf="product.description"
-
Property binding example:
[title]="product.name + ' details'"
-
Custom property binding example:
[product]="product"
-
Event binding example:
(click)="share()"
-
Custom event binding example:
(notify)="onNotify()"
- this can be combined with the child component's
@Output() notify = new EventEmitter();
(TS) and(click)="notify.emit()"
(HTML), and then this will trigger the child component's(notify)="onNotify()"
(HTML) that is written inside the parent component's markup (HTML) to trigger the parent'sonNotify()
.
- this can be combined with the child component's
To start understanding the files more, start here: /src/app/product-list
--> the TS file links to the HTML and CSS files with:
// this is a decorator:
@Component({
selector: "app-product-list", // <app-product-list> tag in DOM
templateUrl: "./product-list.component.html",
styleUrls: ["./product-list.component.css"],
})
// (this decorator indicates that the class in the later lines is a component)
export class ProductAlertsComponent implements OnInit {
// the @Input() decorator indicates that the [product] prop data is passed in from the component's parent
@Input() product;
// the @Output() decorator combined with EventEmitter
// lets us trigger an event with the [notify] prop changes,
// and you can do (click)="notify.emit()" in the child HTML,
// and (notify)="onNotify()" in the parent HTMl will run
@Output() notify = new EventEmitter();
constructor() {}
ngOnInit() {}
}
If you change the selector
to ".app-product-list"
then it'll be <div class="app-product-list">
in the DOM.
You can generate a component with ng generate component component-name
or with ng g component component-name
(https://angular.io/cli/generate#component). It'll create a folder with 4 files in it (.css, .html, .spec.ts, and .ts).
I didn't have to explicitly import TS or HTML files. It just figured it out by the consistent naming! I tried sibling folders under /app
and also tried moving the child component's folder inside its parent component's folder, and it also worked! Just use ng g component component-name
!
Routing/Navigation
<details> <summary>Click to expand/collapse:</summary>https://angular.io/start/start-routing
For example, associating a URL path with a component.
I needed some help getting my local my-app
to work: https://www.smashingmagazine.com/2018/11/a-complete-guide-to-routing-in-angular/
cd my-app
npm i
ng serve
# http://localhost:4200
cd my-app
ng g component
- http://localhost:4200/
- http://localhost:4200/products/someID
- http://localhost:4200/products/anotherID
- http://localhost:4200/products/otherID
<router-outlet></router-outlet>
<div *ngFor="let product of products">
<a [title]="'Product name'" [routerLink]="['/products', product.id]"
>{{ product.name }}</a
>
</div>
<p>{{ product.description }}</p>
<a [title]="'Back to main'" [routerLink]="['/']">Back to main</a>
import { RouterModule } from "@angular/router";
import { ProductDetailsComponent } from "./product-details/product-details.component";
import { ProductListComponent } from "./product-list/product-list.component";
// ...
@NgModule({
declarations: [AppComponent, ProductDetailsComponent, ProductListComponent],
imports: [
BrowserModule,
RouterModule.forRoot([
{ path: "", component: ProductListComponent },
{ path: "products/:productId", component: ProductDetailsComponent },
]),
],
providers: [],
bootstrap: [AppComponent, ProductListComponent, ProductDetailsComponent],
})
export class AppModule {}
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-product-list",
templateUrl: "./product-list.component.html",
styleUrls: ["./product-list.component.css"],
})
export class ProductListComponent implements OnInit {
products: any[];
constructor() {
this.products = [
{
id: "someID",
name: "Some product name",
description: "Some product description.",
},
{
id: "anotherID",
name: "Another product name",
description: "Another product description.",
},
{
id: "otherID",
name: "Other product name",
description: "Other product description.",
},
];
}
ngOnInit(): void {}
}
</details>
Deployment/building/hosting, using Firebase, etc.
https://angular.io/start/start-deployment
Older notes
Following a YouTube tutorial for Angular 8: https://github.com/hchiam/learning-angular8
More notes
https://github.com/hchiam/learning-front-end-frameworks/tree/main/angular