icon picker
TIP - CODE :: SYNTAX ❤️✅

TIP - CODE :: SYNTAX❤️✅
~~~~~~
TIP - TYPESCRIPT ::❤️❤️❤️
—————————————————————————————————————
Để không bị sai dữ liệu ==> syntax:: array.filter.filter.map.sort
—————————————————————————————————————
Sử dụng enum, ép ns về dạng chỉ mục số
Export enum abc -> sau đó ta dùng a = abc.indexof(‘b’);
log(abc[a+1]) -> enum tiếp theo của abc
—————————————————————————————————————
Sử dụng hasError để kiểm tra có lỗi
prePaymentForm.get('amount')?.hasError('min')"
—————————————————————————————————————
const { BBAN, interestSettlementAccount, currency } = this.termDepositInfo!;
—————————————————————————————————————
Khi chỉ dùng 1 input với 1 control
<input class="textarea-inline-control"
[formControl]="titleControl">
titleControl = new FormControl('abc');
—————————————————————————————————————
Dùng form ntn
form.get('toAccountNumber')
form.hasError('required', 'toAccountNumber')
—————————————————————————————————————
Dùng *ngIf sau đó dùng syntax “as avarible” để thực hiện gán tên biến
*ngIf="contactInfo.additions?.provinceName as provinceName"
—————————————————————————————————————
Loading cũng có thể được gọi nên, nếu ko muốn dùng biến abc = false
<div *ngIf="article$ | async as article else loadingTmpl">
<ng-template #loadingTmpl>
Loading...
</ng-template>
Cách dùng div và ng-container::
Dùng div: khi mình có dựa vào class của div
Dùng ng-container: khi mình không cần dựa vào gì từ class=“”
—————————————————————————————————————
Dùng cho HTML - dirty = true :: khi formControl được change, được vấy bẩn, click vô thì ko sao!
*ngIf="form.get('amount')?.dirty && form.hasError('amountRequired', 'amount')"
—————————————————————————————————————
Thêm dấu `+` ở đầu mỗi biến là ép kiểu cho biến đó là number
—————————————————————————————————————
Khi muốn thay đổi 1 biến ở service thì hãy dùng 1 hàm set::rồi gọi thông qua gn đó
—————————————————————————————————————
Có thể dùng syntax này thay cho Object.asign()
this.h = {...this.h ? this.h : hConfig, ...value}
== this.h = {this.h, …value}
—————————————————————————————————————
✅Sử dụng Destructuring assignment để gán product luôn, coi như tạo 1 biến tên product hứng lấy product bên trong object:: account: {product: {}}
.filter(({ product }) => ListFromAccountsOwnAccept.includes(product?.externalId || ''))
—————————————————————————————————————
Object.values:: trả về 1 mảng
Sau đó dùng map():: kiểm tra id có trong mảng này ko?
Return boolean::
Object.values(CURRENT_ACCOUNT_CATEGORIES).map(item => item.id).includes(‘externalId’);
—————————————————————————————————————
Muốn ép kiểu sang string từ number thì dùng ntn
this.valueInput = `${amount}`
—————————————————————————————————————
Sử dung “document” bằng cách inject vào ts
@Inject(DOCUMENT) private document: Document
if (this.document.defaultView) {
this.document.defaultView.scrollTo({ top: 0 });
}
—————————————————————————————————————
Khi 1 variable để ở chế độ public thì sẽ không cần fn setVariable(value: string)
—————————————————————————————————————
Regex:: ‘^[a-zA-Z0-9. ,-]*$’ -> Match với những ký tự trong [a-zA-Z0-9. ,-]
const regEx = new RegExp('^[a-zA-Z0-9. ,-]*$'); // Allows a-z, A-Z, 0-9, space, dot, comma, dash
if (!regEx.test(c.value)) {
errors.descriptionInvalid = true;
}
—————————————————————————————————————
Sử dụng gói lib date-fns để check time ago, isAfter, isBefore, v…v..
isSameDay(new Date(transaction.valueDate), subDays(startDateFilter, 2)
—————————————————————————————————————
Sử dụng slice() để copy mảng thành mảng mới
const arr = arrCurrent.slice()
—————————————————————————————————————
Khi muốn theo dõi 1 biến (subject, …) mà modifine là private, muốn export cho thằng khác dùng thì “this.navHeaderSource.asObservable”
private navHeaderSource = new Subject<string>();
getNavHeaderSource(): Observable<string> {
return this.navHeaderSource.asObservable();
}
—————————————————————————————————————
Sử dụng hoạt ảnh, dùng animations của ANGULAR
—————————————————————————————————————
Khi static is false => template? ; static: true => template!
@ViewChild(TemplateRef, { static: false }) template?: TemplateRef<any>;
—————————————————————————————————————
Sử dụng toán tử ||, && trong typescript
a || b; =>> a ? a : b;
a && b; =>> a ? b : a
~> Áp dụng được trong html và ts
—————————————————————————————————————
Sử dụng destructuring object/array - tip
+ Assignment to new variables: Gán giá trị cho 1 biến mới
const obj = {obj1: {a: 1, b: 2, c: 3}, obj2: ‘oibj2’};
const {param1, param2} = obj ~ obj = {param1, param2}
const {obj1: obj1Ass, obj2: obj2Ass} = obj;
console.log(obj1Ass, obj2Ass);
—————————————————————————————————————
Sử dụng @ContentChild/@ContentChildren
@ContentChild (1)
+ Directive cung cấp thêm tính năng của 1 phần tử (Dom node, component…)::
@Directive({
selector: 'ng-template[tabPanelContent]'
})
-> Directive có thể taget bất kỳ thẻ <ng-template> nào kèm attribute [tabPanelContent]
+ Lúc này ta sẽ khởi tạo 1 biến để truy cập vào content::
@ContentChild(TabPanelContentDirective, {static: true}) explicitBody: TemplateRef<unknown>;
-> Như vậy ta có thể sử dụng::
<app-tab-panel>
<ng-template tabPanelContent> content_* </ng-template>
</app-tab-panel>
=>> Lúc này variable explicitBody sẽ nhận vào 1 template::
<ng-template tabPanelContent> content_* </ng-template>
@ContentChildren (2)
(Cách chúng ta query list template)
+ ContentChildren sẽ được init trước khi lifecycle ngAfterContentInit được call, đây là thời điểm để thao tác
+ Lắng nghe changes để update
Note:: Khái niệm giữa view và content
View:: là những cái như html, css
Content:: là những phần được truyền từ bên ngoài vào component
-> nó là <ng-content> hứng toàn bộ phần view từ ngoài
Ex: Dùng đơn giản:: <app><div>a</div></app> -> <ng-content></ng-content>
—————————————————————————————————————
Sử dụng @ViewChild/@ViewChildren
Using viewChild with DOM Elements
+ ViewChild giúp truy cập các phần tử DOM gốc có biến tham chiếu mẫu
<input #tempInput class=“” />
@ViewChild(‘tempInput’) inputEl: ElementRef
_> nếu là 1 tag div hay muốn lấy 1 tập hợp template::
<div #card>blala…</div>
@ViewChild(‘card’) card: TemplateRef<any>;
Using ViewChild with Child Components
+ Tạo component
+ Tại thằng cha sử dụng component thì định nghĩa 1 variable::
@ViewChild(AbcComponent) abc: AbcComponent;
ngAfterViewInit(){
console.log(this.abc.fn());
}
—————————————————————————————————————
Khi ở trong form, không nên gọi hàm từ attribute trả về
Ex: [disabled]="isInvalidData()"
=> Mỗi lần trên form nhận action thì attribute sẽ trigger vào hàm để checking
—————————————————————————————————————
Dấu chấm than (!) trong typescript có nghĩa là::
~> Báo với typescript rằng biến này sẽ được gán 1 giá trị, do vậy ko cần báo lỗi
—————————————————————————————————————
List dùng với map(fn(data: IData))
this.list.map(fnMap(data)); //fnMap trả về giá trị cho object list
export const fnMap =(data: IData) => (dataForMap: IData) => {return {…dataForMap, variableAdd: value}}; //Thực hiện nhận vào data và trả về object list.
—————————————————————————————————————
Xử lý nhận ng-content
<ng-content select="[errors]"></ng-content>
Bên ngoài truyền vào chỉ điểm ->
<wrapper>
<ng-container [ngSwitch]="getAmountError" errors>
</wrapper>
—————————————————————————————————————
Memory leak {A}
~ Do cách code (lý do duy nhất để xảy ra memory leak)
~ Xảy ra với những operators (không bao giờ complete)::
+ subject & behaveSubject (service - global), interval, timeout

Những case cần / ko cần (unsubcribe )
+ EventEmitter → k
+ Subject in component → k
+ Subject in sevice → c
+ ActiveRouter → k
+ Subscribe vào một observable từ một service → c
+ HttpClient → c/k
c → subscribe vào chính Obs mà sd pipe operator thì có thể cần unsubcribe
k → như trên mà ko sd pipe thì ko cần unsubscribe
+ pipe angular → k
—————————————————————————————————————
~~~~~~
TIP - SERVICE::❤️❤️❤️✅
—————————————————————————————————————
Cách xử lý mỗi lần api trả về
.pipe(
take(1),
pluck('body'),
filter((res) => res !== null && Object.keys(res).length > 0),
finalize(() => this.isLoading.next(false))
)
—————————————————————————————————————
tap((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
paymentOrdersInterceptorService.setValidateResponse(ev.body);
}
})
—————————————————————————————————————
Xử lý tạo ra bắn lỗi trong steam call service
tap(() =>{ throw new HttpErrorResponse({
status: 400,
error:{
errorMessage:' abc',
errorCode: 300
}
})}),
—————————————————————————————————————
filter(id => !!id)
Lọc chỉ call khi id tồn tại, khác undefinded
—————————————————————————————————————
debounceTime(3000 ~ timeout) | delay(3000 ~ timeout)
debounceTime:: Khi sử dụng với sự kiện:: nếu đủ timeout thì nó sẽ trả ra, còn không đủ timeout thì nó sẽ bỏ qua, ko log gì cả
—————————————————————————————————————
Sử dụng iif của RxJS để kiểm tra hàm trước đúng thì chạy hàm sau
getBackgroundList$ = this.showDialogSubject$.asObservable()
.pipe(
switchMap(isShowDialog =>
iif(() => !!isShowDialog,
this.userBackgroundControllerHttpService
.getActiveFolderBackground()
)
),
takeUntil(this._tcbDestroyService)
);
—————————————————————————————————————
Chăm chỉ viết pipe::
—————————————————————————————————————
Mỗi lần nhập sẽ emit về
(input)="onInput($event)"
—————————————————————————————————————
Có thể viết ntn để set type ‘px’|’%’ stype cho css
[ngStype]=”{'width.px': cardWidth, 'height.px': cardHeight}
—————————————————————————————————————
Tách code xử lý ra (khi 2 hàm phụ thuộc vào cùng 1 biến và chạy trong cùng 1 hàm onInit())
~ Ta có 1 biến cần gán data và 2 hàm (1 hàm gọi gán data, 1 hàm dùng data đó)
~ Cả 2 hàm sẽ gọi trong onInit()
~ Xử lý như sau:
+ Ta defined 1 biến dataAss, active$ (behavorSubject)
+ Hàm (1): gọi lấy data gán cho biến (dataAss) và gọi active$.next()
+ Khi đó acctive$ được call, và điều đó sẽ chạy hàm (2) mà ta đã đăng ký ở onInit()
+ Khi đó biến dataAss đã được gán data rồi.

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.