Angular Quickstart
Angular 17+ standalone components.
Install
bash
npm install maplibre-glComponent
ts
// map.component.ts
import {
Component, ElementRef, ViewChild,
AfterViewInit, OnDestroy
} from '@angular/core';
import maplibregl, { Map } from 'maplibre-gl';
@Component({
selector: 'app-map',
standalone: true,
template: `<div #mapEl class="map"></div>`,
styles: [`.map { width: 100%; height: 100vh; }`]
})
export class MapComponent implements AfterViewInit, OnDestroy {
@ViewChild('mapEl') el!: ElementRef<HTMLDivElement>;
private map?: Map;
ngAfterViewInit(): void {
const key = import.meta.env['NG_APP_MFD_PUB_KEY'];
this.map = new maplibregl.Map({
container: this.el.nativeElement,
style: `https://api.mapsfordevs.com/styles/standard.json?key=${key}`,
center: [28.04, -26.20],
zoom: 11
});
}
ngOnDestroy(): void { this.map?.remove(); }
}css
/* styles.css — global */
@import 'maplibre-gl/dist/maplibre-gl.css';Service
ts
// services/mapsfordevs.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { firstValueFrom } from 'rxjs';
export interface GeocodeItem {
lat: number; lng: number; label: string;
confidence: number; type: string;
}
interface Resp<T> { ok: boolean; items?: T[]; error?: string; }
@Injectable({ providedIn: 'root' })
export class MapsForDevsService {
private base = 'https://api.mapsfordevs.com';
private key = import.meta.env['NG_APP_MFD_PUB_KEY'];
constructor(private http: HttpClient) {}
async geocode(query: string, country?: string, limit = 5): Promise<GeocodeItem[]> {
const params: Record<string, string> = { q: query, limit: String(limit) };
if (country) params['country'] = country;
const body = await firstValueFrom(
this.http.get<Resp<GeocodeItem>>(`${this.base}/geocode/forward`, {
params,
headers: { Authorization: `Bearer ${this.key}` }
})
);
if (!body.ok) throw new Error(body.error);
return body.items ?? [];
}
}Register HttpClient in app.config.ts:
ts
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [provideHttpClient()]
};Signal-based language switcher
ts
import { Component, signal, effect, inject } from '@angular/core';
import { MapStateService } from './map-state.service';
@Component({
selector: 'app-lang-picker',
standalone: true,
template: `
<select [value]="lang()" (change)="lang.set($any($event.target).value)">
<option value="en">English</option>
<option value="de">Deutsch</option>
<option value="ja">日本語</option>
</select>
`
})
export class LangPickerComponent {
private mapState = inject(MapStateService);
lang = signal('en');
constructor() {
effect(() => {
const map = this.mapState.map();
const l = this.lang();
if (!map || !map.isStyleLoaded()) return;
['place_label', 'transportation_name', 'poi_label'].forEach(id =>
map.setLayoutProperty(id, 'text-field', [
'coalesce', ['get', `name:${l}`], ['get', 'name:latin'], ['get', 'name']
])
);
});
}
}