Skip to content

Instantly share code, notes, and snippets.

View Armenvardanyan95's full-sized avatar

Armen Vardanyan Armenvardanyan95

View GitHub Profile
function notEmptyArray(
path: FieldPath<unknown[]>,
// define a condition for when to perform a check
// by default, validate always
options: {when: () => boolean} = {when: () => true},
) {
validate(path, (ctx) => {
const value = ctx.value();
if (options.when() && value.length === 0) {
return customError({
function passwordsEqual(path: FieldPath<{
password: string; confirmPassword: string
}>) {
validate(path, (ctx) => {
const value = ctx.value();
if (value.password !== value.confirmPassword) {
return customError({ kind: 'notEqual', message: 'Passwords must match' });
}
return null;
});
function password(path: FieldPath<string>) {
validate(path, (ctx) => {
const value = ctx.value();
if (value && value.length < 8) {
// you can return different errors for different cases using the "kind" field
return customError({
kind: 'tooShort', message: 'Password must be at least 8 characters long',
});
}
if (value && !/[A-Z]/.test(value)) {
@Injectable({providedIn: 'root'})
export class PortalService {
// we can have multiple portals
portals = signal<Record<string, TemplateRef<any>>>({});
// get one of the templates to use in your component
getPortal(portalName: string) {
return computed(() => this.portals()[portalName]);
}
export class TodoStore {
readonly #todoService = inject(TodoService);
query = signal('');
todosResource = httpResource(() => ({
url: '/api/todos',
params: { q: this.query() },
method: 'get',
}),
// use a default value and parsing with Zod
{defaultValue: [], parse: todoListSchema.parse});
@Component({
template: `
@if (todo.hasValue()) {
<form (ngSubmit)="save()">
<input [(ngModel)]="todo.value().title" />
<button type="submit">Save</button>
</form>
}
`,
imports: [FormsModule],
import { Component, computed, effect, inject, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { forkJoin } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';
@Component({
template: `
@if (loading()) {
<div>Loading...</div>
} @else {
@Component({
template: `
@if (todos.hasValue()) {
<select [(ngModel)]="todoId">
@for (todo of todos.value(); track todo.id) {
<option [value]="todo.id">{{ todo.title }}</option>
}
</select>
}
@if (todo.hasValue()) {
@Component({
template: `
@if (todos.hasValue()) {
<select [(ngModel)]="todoId">
@for (todo of todos.value(); track todo.id) {
<option [value]="todo.id">{{ todo.title }}</option>
}
</select>
}
@if (todo.hasValue()) {
type ModelTypes = 'product' | 'order';
type Product = {productName: string};
type Order = {orderId: number};
type Model = {
id: number;
type: ModelTypes;
entity: Product | Order;
}