Skip to content

Instantly share code, notes, and snippets.

@unlocomqx
Last active October 11, 2025 14:41
Show Gist options
  • Save unlocomqx/951ebf29148d269c9737fa9c31381f28 to your computer and use it in GitHub Desktop.
Save unlocomqx/951ebf29148d269c9737fa9c31381f28 to your computer and use it in GitHub Desktop.
import { Component, signal, computed, effect, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { toSignal } from '@angular/core/rxjs-interop';
import { from, switchMap, startWith } from 'rxjs';
@Component({
selector: 'app-chained-selects',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './chained-selects.component.html',
styleUrls: ['./chained-selects.component.css'],
})
export class ChainedSelectsComponent implements OnInit {
public selectedState = signal<string | undefined>(undefined);
public selectedCity = signal<string | undefined>(undefined);
public states = toSignal(from(getStates()), { initialValue: [] as string[] });
private cities$ = computed(() => {
const state = this.selectedState();
if (state) {
return from(getCities(state)).pipe(
startWith([] as string[])
);
}
return from(Promise.resolve([] as string[]));
});
public cities = toSignal(this.cities$().pipe(
switchMap(obs => obs)
),
{ initialValue: [] as string[] }
);
public isFetchingCities = computed(() => {
const citiesValue = this.cities();
const stateSelected = !!this.selectedState();
return stateSelected && citiesValue.length === 0;
});
ngOnInit(): void {
const initialStates = this.states();
if (initialStates.length > 0) {
this.selectedState.set(initialStates[0]);
}
effect(() => {
const availableCities = this.cities();
if (availableCities.length > 0) {
this.selectedCity.set(availableCities[0]);
} else {
this.selectedCity.set(undefined);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment