learn links

Client login and register

Learning goals

  • Creating components using the Angular CLI
  • Using Angular Template forms
  • Using Angular services
  • Understanding Observables
  • Using Angular structural directives to confitionally display elemetns on a page
  • Component communication from parent to child
  • Component communication from child to parent

folder:

  • layout: navbar,…
  • features: members related components, messages, accounts,…
  • core: angular services
  • shared: shared components LIFT principle:
  • Locate
  • Identify
  • Flat
  • Try to be Dry #Angular
ng generate
OR
ng g --help
ng c --help
ng g c nav --dry-run
ng g c layout/nav --dry-run
ng g c layout/nav --skip-tests --dry-run

Changes angular.json:

"schematics": {
        "@schematics/angular:component": {
          "skipTests": true,
          "path": "src"
        }
      },
ng g c layout/nav --dry-run
ng g c layout/nav 

css flexbox Note Flexbox Froggy - A game for learning flexbox

Justify-content là gì?

Dùng để căn chỉnh các phần tử con bên trong container theo trục chính (main axis). Mặc định trục chính là ngang từ trái sang phải (flex-direction: row). 🔹 Các giá trị chính:

  1. flex-start (MẶC ĐỊNH) 📌 Các phần tử dồn về bên trái (đầu trục chính). Ví dụ: justify-content: flex-start; 📷 Kết quả: 🟩🟩🟩⬜⬜⬜⬜⬜⬜
  2. flex-end 📌 Các phần tử dồn về bên phải (cuối trục chính). Ví dụ: justify-content: flex-end; 📷 Kết quả: ⬜⬜⬜⬜⬜⬜🟩🟩🟩
  3. center 📌 Các phần tử căn giữa container theo chiều ngang. Ví dụ: justify-content: center; 📷 Kết quả: ⬜⬜⬜🟩🟩🟩⬜⬜⬜
  4. space-between 📌 Các phần tử cách đều nhau, phần tử đầu ở bên trái, phần tử cuối ở bên phải. Không có khoảng ở rìa ngoài. Ví dụ: justify-content: space-between; 📷 Kết quả: 🟩⬜⬜⬜🟩⬜⬜⬜🟩 (3 phần tử → khoảng cách giữa 2 phần tử là đều nhau, rìa ngoài không có khoảng trắng)
  5. space-around 📌 Các phần tử có khoảng cách đều xung quanh. → Có nửa khoảng trống ở 2 bên rìa, khoảng giữa thì gấp đôi. Ví dụ: justify-content: space-around; 📷 Kết quả: ⬜🟩⬜⬜🟩⬜⬜🟩⬜ (Khoảng ở hai bên nhỏ hơn khoảng giữa)
  6. space-evenly 📌 Các phần tử cách nhau đều hoàn toàn (bao gồm cả 2 bên rìa). (Không phải game Flexbox Froggy nào cũng có giá trị này) Ví dụ: justify-content: space-evenly; 📷 Kết quả: ⬜⬜🟩⬜⬜🟩⬜⬜🟩⬜⬜ (Các khoảng cách = nhau tuyệt đối)

🧠 Tóm tắt nhanh:

Giá trịCăn chỉnhKhoảng cách rìa ngoài?
flex-startDồn về tráiKhông
flex-endDồn về phảiKhông
centerCăn giữaCó (tính toán tự động)
space-betweenCách đều, không có rìaKhông
space-aroundCách đều có rìa nhỏ
space-evenlyCách đều cả trong & rìaCó (đều tuyệt đối)

Level 1:

justify-content: flex-end;

Level 2:

justify-content: center;

Level 3:

justify-content: space-around;

Level 4:

justify-content: space-between;

align-items là gì?

Dùng để căn các phần tử con theo chiều dọc (trục phụ) trong container. Trục phụ là vuông góc với trục chính. Mặc định flex-direction: row → trục phụ là chiều dọc Mặc định flex-direction: column → trục phụ là chiều ngang 👉 Trong game Flexbox Froggy, thường dùng mặc định (row), nên align-items điều khiển vị trí theo trục dọc (trên ↕️ dưới). 🔹 Các giá trị chính:

  1. flex-start 📌 Căn phần tử về đầu trục phụ, tức là trên cùng. Kết quả: Ếch ở sát đỉnh ao (top) align-items: flex-start;
  2. flex-end 📌 Căn phần tử về cuối trục phụ, tức là dưới cùng. Kết quả: Ếch ở đáy ao (bottom) align-items: flex-end;
  3. center 📌 Căn giữa theo trục phụ → giữa chiều cao của container align-items: center;
  4. baseline 📌 Căn các phần tử theo dòng cơ sở của chữ (baseline), thường dùng với phần tử có text ⚠️ Trong Flexbox Froggy thì baseline ít thấy hiệu quả vì các ếch không có văn bản align-items: baseline;
  5. stretch (mặc định) 📌 Các phần tử giãn chiều cao (hoặc chiều ngang) để lấp đầy container, nếu không đặt height cụ thể. align-items: stretch; 🧪 Ví dụ trực quan: Giả sử bạn có 3 con ếch (divs) trong một hàng (flex-direction: row)
🐸
🐸
🐸
Căn dưới: .pond { display: flex; align-items: flex-end; } → Tất cả ếch đứng ở đáy container. ## 🧠 Tóm tắt bảng so sánh:
Giá trịHiệu ứng (khi flex-direction: row)
flex-startCác item nằm trên cùng
flex-endCác item nằm dưới cùng
centerCác item nằm chính giữa dọc
baselineCăn theo dòng chữ (nếu có)
stretchKéo giãn chiều cao của item cho bằng container

Level 5:

align-items: flex-end;

Level 6:

justify-content: center;
align-items: center;

Level 7:

justify-content: space-around;
align-items: flex-end;

Cú pháp:

flex-direction: <giá trị>;

Các giá trị và ý nghĩa:

Giá trịMô tả ngắnTrục chínhHướng
row (mặc định)Sắp xếp từ trái ➡ phảiNgang (→)Bình thường (LTR)
row-reverseSắp xếp từ phải ➡ tráiNgang (→)Ngược
columnSắp xếp từ trên ⬇ dướiDọc (↓)Bình thường
column-reverseSắp xếp từ dưới ⬆ trênDọc (↓)Ngược

🐸 Trong game Flexbox Froggy:

Khi ếch không khớp vị trí với lá sen, thì bạn cần đảo thứ tự bằng flex-direction.

Ví dụ:

Giả sử bạn có 3 con ếch và chúng đang từ trái qua phải, nhưng lá sen yêu cầu từ phải qua trái, bạn viết: flex-direction: row-reverse;

Minh họa trực quan:

Giả sử có HTML: <div class="pond"> <div>🐸1</div> <div>🐸2</div> <div>🐸3</div> </div>

flex-direction: row;

🐸1 — 🐸2 — 🐸3 (từ trái qua phải)

flex-direction: row-reverse;

🐸3 — 🐸2 — 🐸1 (từ phải qua trái)

flex-direction: column;

🐸1
🐸2
🐸3

flex-direction: column-reverse;

🐸3
🐸2
🐸1


🧠 Mẹo ghi nhớ:

  • row = theo chiều ngang, giống như văn bản
  • row-reverse = đảo thứ tự ngang
  • column = sắp từ trên xuống
  • column-reverse = sắp từ dưới lên

Level 8:

flex-direction: row-reverse;

Level 9:

flex-direction: column;

Level 10:

justify-content: flex-end;
flex-direction: row-reverse;

Level 11:

flex-direction: column;
justify-content: flex-end;

Level 12:

flex-direction: column-reverse;
justify-content: space-between;

Level 13:

flex-direction: row-reverse;
justify-content: center;
align-items: flex-end;

🔹 Cú pháp:

order: <số nguyên>;

Cách hoạt động:

  • Mặc định mọi phần tử đều có order: 0.
  • Phần tử nào có order nhỏ hơn thì đứng trước, lớn hơn thì đứng sau.
  • Bạn có thể dùng số âm (-1, -2) hoặc dương (1, 2, 3, …).

Ví dụ minh họa:

Giả sử có HTML: <div class="pond"> <div class="frog green"></div> <div class="frog yellow"></div> <div class="frog red"></div> </div>

🐸 Mục tiêu:

Đưa các con ếch đến đúng vị trí lá sen theo thứ tự: red → yellow → green
(Trong HTML thì lại là green → yellow → red)

➡ CSS:

.frog.green { order: 3; } .frog.yellow { order: 2; } .frog.red { order: 1; } → Kết quả: red đứng trước, rồi yellow, rồi green.

🧠 Ghi nhớ:

  • Số order nhỏ hơn → đứng trước
  • Số order lớn hơn → đứng sau
  • Có thể dùng số âm để đẩy phần tử ra phía trước

📌 Trong Flexbox Froggy:

Bạn sẽ thấy 3 con ếch, ví dụ: .green { order: 2; } .yellow { order: 1; } .red { order: 3; } → yellow → green → red


Level 14:

order: 2;

Level 15:

order:-3

🔹 Cú pháp:

.item { align-self: flex-start | flex-end | center | baseline | stretch; }

Ý nghĩa các giá trị:

Giá trịGiải thích
flex-startCăn lên đầu của container (trục dọc nếu flex-direction: row)
flex-endCăn xuống cuối của container
centerCăn giữa trục dọc
baselineCăn theo dòng chữ (baseline) của nội dung
stretch (mặc định)Kéo giãn phần tử để đầy chiều dọc container

So sánh với align-items:

align-itemsÁp dụng cho tất cả phần tử con trong container
align-selfÁp dụng cho một phần tử duy nhất

🐸 Ví dụ trong Flexbox Froggy:

Giả sử có 3 con ếch và bạn muốn chỉ con màu vàng nằm dưới đáy, còn các con khác nằm ở giữa:

.yellow { align-self: flex-end; } Các con khác vẫn giữ theo align-items: center; (hoặc mặc định).


Level 16:

align-self: flex-end;

Level 17:

order: 1;
align-self: flex-end;

🧠 Tổng quan về flex-wrap

.container { flex-wrap: nowrap | wrap | wrap-reverse; }

💡 Ý nghĩa:

Giá trịGiải thích
nowrap (mặc định)Các phần tử không xuống dòng, dù không đủ chỗ (có thể bị bóp nhỏ lại)
wrapCác phần tử tự động xuống dòng khi không đủ chỗ
wrap-reverseGiống wrap, nhưng dòng mới hiện ở trên thay vì dưới

🐸 Trong Flexbox Froggy:

Giả sử có 6 con ếch, mà flex-wrap: nowrap thì tất cả sẽ nằm trên một dòng, bị co lại nhỏ xíu để vừa container. Khi bạn thêm: flex-wrap: wrap; → Chúng sẽ tự động dàn sang dòng kế tiếp nếu không đủ không gian trên một dòng.

📌 Ghi nhớ:

  • nowrap: ép tất cả phần tử nằm trên 1 dòng.
  • wrap: cho phép xuống dòng (theo hướng bình thường: dòng sau nằm bên dưới).
  • wrap-reverse: xuống dòng nhưng dòng sau nằm lên trên. 📍 Bạn có thể thử trực tiếp với đoạn sau trong Flexbox Froggy: flex-wrap: wrap; → Các con ếch sẽ bung ra thành nhiều dòng nếu container nhỏ.

Level 18:

flex-wrap: wrap;

Level 19:

flex-wrap: wrap;
flex-direction: column;

shorthand property (viết tắt) trong CSS gọi là flex-flow – dùng để kết hợp hai thuộc tính:

  • flex-direction
  • flex-wrap

🧠 Cú pháp flex-flow:

.container { flex-flow: <flex-direction> <flex-wrap>; } Ví dụ: flex-flow: row wrap; Tương đương với: flex-direction: row; flex-wrap: wrap;

Các giá trị hợp lệ:

flex-directionflex-wrap
rownowrap (mặc định)
row-reversewrap
columnwrap-reverse
column-reverse

Chỉ cần nhớ là thứ tự là: direction trước, wrap sau (cách nhau bằng dấu cách).

🐸 Trong Flexbox Froggy:

Đã học flex-direction: column-reverse;flex-wrap: wrap-reverse;
Thì có thể viết gọn lại thành: flex-flow: column-reverse wrap-reverse; Tương tự, nếu đề bài yêu cầu:

  • Hiển thị từ trên xuống (column)
  • Và cho phép xuống dòng (wrap) → Bạn viết: flex-flow: column wrap;

📝 Tổng kết:

Viết dàiViết ngắn (flex-flow)
flex-direction: row;flex-flow: row nowrap;
flex-direction: column; + flex-wrap: wrap;flex-flow: column wrap;
flex-direction: row-reverse; + flex-wrap: wrap-reverse;flex-flow: row-reverse wrap-reverse;

Level 20:

flex-wrap: wrap;
flex-direction: column-reverse;

🧠 Khác biệt giữa align-itemsalign-content

align-itemsalign-content
Căn chỉnh từng item theo chiều dọcCăn chỉnh các hàng (lines) theo chiều dọc
Áp dụng cho mọi layout (kể cả 1 dòng)Chỉ có tác dụng khi có nhiều dòng (flex-wrap: wrap)
Tác động tới vị trí của từng itemTác động tới khoảng cách giữa các dòng

Các giá trị của align-content

Giá trịÝ nghĩa dễ hiểu
flex-startCác dòng nằm sát trên cùng của container
flex-endCác dòng nằm sát dưới cùng của container
centerCác dòng nằm giữa chiều cao của container
space-betweenKhoảng cách bằng nhau giữa các dòng, không có ở rìa
space-aroundKhoảng cách bằng nhau xung quanh mỗi dòng
stretchMỗi dòng giãn ra đều để chiếm hết chiều cao container (mặc định nếu có không gian)

🎯 Minh họa thực tế:

Giả sử có 3 dòng ếch, mỗi dòng có 3 con 🐸🐸🐸:

  • align-content: flex-start: tất cả 3 dòng dồn lên trên cùng.
  • align-content: flex-end: tất cả 3 dòng dồn xuống dưới.
  • align-content: center: 3 dòng nằm giữa chiều cao.
  • align-content: space-between: dòng đầu nằm trên cùng, dòng cuối dưới cùng, dòng giữa nằm giữa (cách đều).
  • align-content: space-around: mỗi dòng có khoảng trắng trên và dưới đều nhau.
  • align-content: stretch: chiều cao mỗi dòng giãn ra để lấp đầy container.

🚫 Lưu ý:

Nếu chỉ có 1 dòng duy nhất, align-content không có tác dụng. Trong trường hợp đó, bạn dùng align-items thay.


✅ Tóm lại:

Khi nào dùng?Dùng gì?
Có nhiều dòng?align-content
Chỉ 1 dòng item?align-items
Căn từng item riêng lẻ?align-self

Level 21:

align-content: flex-start;

Level 22:

align-content: flex-end;

Level 23:

flex-direction: column-reverse;
align-content: center;

Level 24:

flex-direction: column-reverse;
flex-wrap: wrap-reverse;
justify-content: center;
align-content: space-between;

🧠 Tóm tắt các thuộc tính cần nhớ:

Thuộc tínhTác dụng chính
justify-contentCăn item theo chiều ngang (main axis)
align-itemsCăn item theo chiều dọc (cross axis)
flex-directionĐổi chiều chính: row / column / reverse
flex-wrapCho phép xuống dòng (wrap) hoặc đảo ngược dòng (wrap-reverse)
flex-flowGộp flex-direction + flex-wrap
align-contentCăn chỉnh các dòng (lines) khi có nhiều dòng
orderĐặt lại thứ tự item (áp dụng từng item riêng)
align-selfCăn chỉnh riêng lẻ từng item (ghi đè align-items)

							   🐸 

🧠 TỔNG HỢP TẤT CẢ THUỘC TÍNH (giải thích dễ hiểu):


🔹 justify-content → Căn theo trục chính

  • flex-start, flex-end, center, space-between, space-around, space-evenly
  • Dùng để căn chỉnh ngang hoặc dọc (tùy theo flex-direction)

🔹 align-items → Căn các item theo trục phụ

  • stretch, flex-start, center, flex-end, baseline
  • Áp dụng cho toàn bộ item (1 dòng)

🔹 flex-direction → Đổi hướng trục chính

  • row (ngang trái qua phải – mặc định)
  • row-reverse, column, column-reverse

🔹 flex-wrap → Cho phép xuống dòng

  • nowrap (mặc định)
  • wrap → khi hết chỗ, item xuống dòng mới
  • wrap-reverse → dòng mới thêm phía trên

🔹 flex-flow → Gộp flex-directionflex-wrap

flex-flow: row wrap; flex-flow: column-reverse nowrap;


🔹 align-content → Căn các dòng (chỉ khi có nhiều dòng – nhờ flex-wrap)

  • flex-start, center, flex-end, space-between, space-around, stretch

⚠️ KHÁC align-items:

  • align-items áp dụng cho các item trong một dòng
  • align-content áp dụng cho cả nhiều dòng (multi-line)

🔹 order → Đổi thứ tự hiển thị của từng item

  • Mặc định: order: 0
  • Bạn gán số: order: -1, order: 3… phần tử nào có số nhỏ sẽ hiển thị trước

🔹 align-self → Ghi đè align-items cho từng item

.frog { align-self: flex-end; }


📌 TỔNG KẾT:

Tên thuộc tínhTác dụng gì?
flex-directionĐổi hướng trục chính
justify-contentCăn item theo trục chính
align-itemsCăn item theo trục phụ (trong 1 dòng)
align-contentCăn toàn bộ dòng (nhiều dòng)
flex-wrapCho phép xuống dòng
flex-flowGộp direction + wrap
orderĐổi thứ tự xuất hiện từng item
align-selfGhi đè align-items cho từng item

Heroicons


ng g --help
ng g s account-service --dry-run

Angular.json:

"schematics": {
        "@schematics/angular:component": {
          "skipTests": true,
          "path": "src"
        },
        "@schematics/angular:service": {
          "skipTests": true,
          "path": "src/core/services"
        }
      },
 
ng g s account-service --dry-run
 
ng g s account-service

Dropbox Daisy UI:

  • Method 1. details and summary
  • Method 2. popover API and anchor positioningnew
  • Method 3. CSS focus

Obserables

  • New sandard for managing async data included in ES7
  • Angular v2
  • They are lazy collections of multiple values over time
  • Think of observables like a newsletter
  • Like a Newsletter
    • Only subscribers of the newsletter receive the newsletter
    • If no-one subcribers to the newsletter it probably will not be printed

So sánh Promise và Observable

Tiêu chíPromiseObservable
Nguồn gốcJavaScript ES6RxJS (Reactive Extensions for JavaScript)
Đơn giá trị / Đa giá trịChỉ trả về một giá trị duy nhấtTrả về nhiều giá trị theo thời gian
Tính lười (Lazy)Không lười — bắt đầu chạy ngay khi tạoLười — chỉ bắt đầu khi được subscribe()
Có thể huỷ (cancel)❌ Không thể huỷ✅ Có thể huỷ bằng unsubscribe()
Toán tử xử lý dữ liệu❌ Không có (chỉ .then().catch())✅ Có nhiều toán tử mạnh (map, filter, merge, reduce, retry, v.v.)
Tái sử dụng❌ Không tái sử dụng✅ Có thể tái sử dụng nhiều lần
Kết thúc (complete)Tự động kết thúc sau khi resolve/rejectPhải chủ động gọi complete() hoặc unsubscribe()
Phổ biến dùng choGọi API đơn giản (REST)Gọi API phức tạp, lắng nghe events, xử lý streams

📌 Ví dụ minh hoạ

1. Promise

getData(): Promise<any> { return fetch('https://api.example.com/data') .then(response => response.json()); }

Sử dụng: this.getData().then(data => { console.log(data); });


2. Observable (RxJS)

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

Sử dụng: this.getData().subscribe({ next: data => console.log(data), error: err => console.error(err), complete: () => console.log('Done') });


📚 Khi nào dùng cái nào?

Tình huốngNên dùng
Gọi API 1 lần đơn giản✅ Promise / Observable đều được
Gọi API và cần xử lý nhiều thao tác (retry, delay)✅ Observable
Theo dõi sự kiện (click, input, WebSocket…)✅ Observable
Thao tác không cần hủy bỏPromise
Cần dừng stream khi component bị hủy (ngOnDestroy)Observable + takeUntil()

💡 Tổng kết

  • Promise: Dễ dùng, thích hợp với thao tác đơn giản, xử lý một lần rồi kết thúc.
  • Observable: Mạnh mẽ hơn, phù hợp với Angular và các thao tác phức tạp, theo thời gian. Làm việc với Angular + HttpClient → nên dùng Observable là mặc định, vì đó là cách Angular hoạt động theo reactive programming.

excalidraw #Angular ts

Subcribe

getMembers(){
	this.service.getMembers().subscribe(members =>
	{
		this.member = members
	}, error =>
	{
		console.log(error);
	}, () =>{
		consolo.log('completed');
	}
	)
}

ToPromise

getMembers(){
	return this.http.get('api/users).toPromise()
}

Async Pipe

<li *ngFor='let member of service.getMembers() | async'>{{member.username}}</>

Automatically subscribes/unscribes from the observable

Signals

A signal is a wrapper around a value that notifies interested consumers when that value changes. Signals can contain any value, from primitives to complex data structures

const count = signal(0);
//signals are getter functions- calling them reads their values.
console.log('The count is:' + count());
// Set a new value
count.set(3);
//Update a value
count.update(value=>value+2)
  • Simplicity and readablility
  • Performance
  • Predictability
  • Intergration

Angular commands:

ng g c features/home --dry-run
ng g c features/home 
ng g c features/account/register

Summary:

  • Use of local storage to persitst token XSS weakness
  • Length of token expiration
  • Password salt in Database ASP.Net Identity

END