icon picker
TIP - CODE ❤️✅

TIP - CODE❤️✅
(Xử lý code bằng cách dễ đọc cho người khác :: luồng dễ hiểu)
TOOL:: control + G :: select nhiều cái giống nhau và sửa cùng 1 lúc
Thằng memory, route-param
Có mối liên kết với nhau, vậy nên khi tạo chỉ cần 2 thằng input và output có cùng tên định nghĩa là ok
Còn thằng navigation chỉ để làm đường dẫn, nếu muốn input nhận được thì dùng thêm router.navigate name@input là ok


có 2 cách sử dụng icon
<bb-icon-ui class='more-pay-body-item__icon' name='stroke1'></bb-icon-ui>
<div [className]="'bill-type-icon tcb-icon-other'"></div>
—————————————————————————————————————
Khi otherServices$ laf observable this ta dung async as oServices, sau đó forEach
<ng-container *ngIf="otherServices$ | async as oServices">
<techcom-select-bill-pay-ui
*ngFor="let service of oServices"
[ngClass]="{ selected: (selectedService$ | async)?.serviceType === service.serviceType }"
></techcom-select-bill-pay-ui>
</ng-container>
—————————————————————————————————————
Sử dụng fieldset của BB
<fieldset class="col-12 col-md-6 bb-fieldset">
<div class="bb-text-support text-medium" i18n="bill-payment-page-review-reference-number-label">
Reference number
</div>
<div class="bb-label text-medium">{{ referenceNumber }}</div>
</fieldset>
—————————————————————————————————————
Cách sử dụng date format (sử dung moment)
Add lib import moment from "moment"
const dateString = moment(new Date()).format('DD MMMM YYYY');
console.log(dateString)
//output -> 13 September 2021
Sửa content add backgroup (dùng after, before)
Gộp những backgroup vào với nhau sử dụng position: absolute ở (before, after) - div bao ngoài thì có position: relative
—————————————————————————————————————
Cách dùng pluck để gom giá trị theo property
//Dùng from, map
pluck(array: any[], key: string){
return Array.from(new Set(array.map((obj: any) => obj[key])));
//Dùng map
let result = goal.map(a => a.category);
let result = goal.map(({ category }) => category)
Link: https://anonystick.com/blog-developer/pluck-javascript-array-2019121866886771
—————————————————————————————————————
Cách để show lên 1 template thôi thì đơn giản dùng
TYPESCRIPT: @ViewChild('monthlyTmp') monthlyTmp: TemplateRef<any> | null = null;
displayTmp: TemplateRef<any> | null = null;
HTML: <ng-container [ngTemplateOutlet]="displayTmp">
</ng-container>
<ng-template #monthlyTmp></ng-template>
-> Xử lý: this.displayTmp = this.monthlyTmp
—————————————————————————————————————
Tạo 1 hành động click custom
<button (myClick)="clickMessage=$event" clickable>click with myClick</button>
File directive: @Directive({selector: '[myClick]'})
export class ClickDirective {
@Output('myClick') clicks = new EventEmitter<string>(); // @Output
toggle = false;
constructor(el: ElementRef) {
el.nativeElement
.addEventListener('click', (event: Event) => {
this.toggle = !this.toggle;
this.clicks.emit(this.toggle ? 'Click! abc' : '');
});
}
}
—————————————————————————————————————
Sử dụng ngTemplate để pass dữ liệu, let-context=“”
<ng-container [ngTemplateOutlet]="estimateTemplate" [ngTemplateOutletContext]="ctx”>
<ng-template #estimateTemplate let-lessonsCounter="abc"
—————————————————————————————————————
if (err instanceof HttpErrorResponse) {
if (err.error instanceof ErrorEvent) {
console.error("Error Event");
} else {
switch (err.status) {
case 401: //login
break;
case 403: //forbidden
break;
}
}
} else {
console.error("some thing else happened");
}
return throwError(err);
—————————————————————————————————————
Xử lý timeout và error tinh tế
this.interestService
.getInterest({
categoryIds,
principalAmount: this.principalAmount
})
.pipe(
timeoutApi(() => this.errorHandlerService.showModalResponseError()),
catchErrorAPI(
(errorMessage, errorCode) => this.errorHandlerService.showModalResponseError(),
() => this.errorHandlerService.showModalResponseError()
),
filter((resp: InterestTable[]) => {
return resp && resp.length > 0;
})
).subscribe({})
———>
function catchErrorAPI<T>(
errorParsedHandler: (errorMessage: Record<string, string>, errorCode?: number | string) => void,
errorHandlerGeneric?: () => void
) {
return function (source: Observable<T>): Observable<T> {
return source.pipe(
catchError((err) => {
if (err instanceof HttpErrorResponse) {
if (!!err.error) {
const { errorCode, errorMessage } = err.error;
if (errorCode != undefined && !!errorMessage) {
errorParsedHandler(errorMessage, errorCode);
return EMPTY;
}
}
if (errorHandlerGeneric) {
errorHandlerGeneric();
return EMPTY;
}
}
return throwError(err);
})
);
};
}
export { catchErrorAPI };
———> Gọi nó trong pipe
—————————————————————————————————————
Truyền input thông qua config pageModel - BB
widgetMode: 'simple',
<property label="Widget Mode (simple | complex)" name="widgetMode" viewHint="text-input,admin,designModeOnly" type="string">
<value type="string">simple</value>
</property>
@Input() widgetMode: WidgetMode = WidgetMode.simple;
—————————————————————————————————————
**Reactive forms (A)
InitForm::
this.initFrom = this.formBuilder.group(
{
description: ['', [this.descriptionValidator.bind(this)]],
availableBalance: [0, Validators.min(1)],
amount: [{ amount: '', currency: CurrencyType.VND },
[amountValidator]
]
},
{ validators: amountAvailableValidator }
);
————**
export function amountValidator(c: AbstractControl): ValidationErrors | null {
if (!c.value.amount || c.value.amount === '0') {
return { amountRequired: true };
}
if (parseFloat(c.value.amount) < 1) {
return { amountInvalid: true };
}
return null;
}
————**
amountAvailableValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
const amountObj: AmountState = control.get('amount')?.value;
const availableBalance: number = control.get('availableBalance')?.value;
if (amountObj && availableBalance) {
const amount = parseFloat(amountObj.amount);
if (amount >= availableBalance) {
control.get('amount')?.setErrors({ insufficientAccountBalance: true });
return { insufficientAccountBalance: true };
}
}
return null;
};
—————————————————————————————————————
Sử dụng concatMap(rxJS) xử lý gọi modal của ngbModal call api sau đó hiển thị modal để xác nhận
this._termDepositHttpService
.withdrawValidateBalance({ tdId: this.product.BBAN! })
.pipe(
concatMap((termDepositInfo) => {
const { loseAmount } = termDepositInfo;
const modalRef = this._ngbModal.open(ConfirmWithdrawTdComponent, { centered: true });
modalRef.componentInstance.amount = loseAmount;
modalRef.componentInstance.productTypeName = productTypeName;
return from(modalRef.result).pipe(
catchError(() => EMPTY),
map(() => ({ ...accountSelectedInfo, ...termDepositInfo }))
);
}),
finalize(() => {
this.isValidatingWithdraw = false;
this._cdr.markForCheck();
})
)
.subscribe({
// Pass data output of widget
next: (data) => {
this._widgetCommunicateService.confirmWithdrawTD.next(data as ConfirmWithdrawTDData)
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.