Skip to content

Instantly share code, notes, and snippets.

View dmitry-stepanenko's full-sized avatar

Dmitriy Stepanenko dmitry-stepanenko

View GitHub Profile
@dmitry-stepanenko
dmitry-stepanenko / .eslintrc-with-type-checker.json
Created July 14, 2024 08:21
separate eslint with type checked
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["tsconfig.*?.json"],
"warnOnUnsupportedTypeScriptVersion": false
},
"plugins": ["rxjs", "rxjs-angular"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
const control = new FormControl('Hello, world!');
control.reset();
console.log(control.value); // null
import { runValueAccessorTests } from 'ngx-cva-test-suite';
import { CounterControlComponent } from './counter.component';
runValueAccessorTests({
/** Component, that is being tested */
component: CounterControlComponent,
/**
* All the metadata required for this test to run.
* Under the hood calls TestBed.configureTestingModule with provided config.
*/
// ... code of CounterComponent
writeValue(value: number) {
// it's convenient to reuse existing "setValue" method, right?
// however, this will lead to the incorrect behavior
this.setValue(value, false);
this._cdr.markForCheck();
}
protected setValue(value: number, emitEvent: boolean) {
this.value = value;
interface ControlValueAccessor {
writeValue(obj: any): void
registerOnChange(fn: any): void
registerOnTouched(fn: any): void
setDisabledState(isDisabled: boolean)?: void
}
// ... code of CounterComponent
writeValue(value: number) {
// it's convenient to reuse existing "setValue" method, right?
// however, this will lead to the incorrect behavior
this.setValue(value);
this._cdr.markForCheck();
}
protected setValue(value: number) {
const parsed = parseInt(value as any);
export class AppComponent {
readonly animal = new FormControl(‘rabbit’);
constructor() {
ctrl.valueChanges.subscribe(console.log);
animal.setValue(‘hare’);
animal.setValue(‘cat’);
}
}
@dmitry-stepanenko
dmitry-stepanenko / a-cva-1.ts
Last active September 14, 2022 06:34
Counter control example for medium article
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
const COUNTER_CONTROL_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CounterControlComponent),
multi: true,
};
@Component({
/**
* Hypertext Transfer Protocol (HTTP) response status codes.
* @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
*/
export enum HttpStatusCodesEnum {
/** No internet connection */
NO_INTERNET_CONNECTION = 0,
/**
* The server has received the request headers and the client should proceed to send the request body
/**
* Returns duration in ms from ISO 8601 string.
* E.g. "PT15M33S" is converted to 933000
*/
export function convertISO8601ToMs(duration: string): number {
const time_extractor = /^P([0-9]*D)?T([0-9]*H)?([0-9]*M)?([0-9]*S)?$/i;
const extracted = time_extractor.exec(duration);
if (extracted) {
const days = parseInt(extracted[1], 10) || 0;
const hours = parseInt(extracted[2], 10) || 0;