import { HttpClient } from '@angular/common/http'; import { Injectable, inject } from '@angular/core'; import { Observable, map } from 'rxjs'; type QueryResult = { docs: T[] }; @Injectable({ providedIn: 'root' }) export class SpacexApiService { private readonly http = inject(HttpClient); private readonly baseUrl = 'https://api.spacexdata.com/v4'; getLaunches(): Observable { return this.http .post>(`${this.baseUrl}/launches/query`, { query: {}, options: { sort: { date_utc: -1 }, pagination: false, populate: [ { path: 'rocket', select: { name: 1 } }, { path: 'launchpad', select: { name: 1 } } ] } }) .pipe(map((result) => result.docs ?? [])); } getRockets(): Observable { return this.http .post>(`${this.baseUrl}/rockets/query`, { query: {}, options: { sort: { first_flight: -1 }, pagination: false } }) .pipe(map((result) => result.docs ?? [])); } getCapsules(): Observable { return this.http .post>(`${this.baseUrl}/capsules/query`, { query: {}, options: { sort: { serial: 1 }, pagination: false } }) .pipe(map((result) => result.docs ?? [])); } getStarlink(): Observable { return this.http .post>(`${this.baseUrl}/starlink/query`, { query: {}, options: { select: { version: 1, longitude: 1, latitude: 1, height_km: 1, velocity_kms: 1, spaceTrack: 1 }, limit: 120, sort: { launch: -1 } } }) .pipe( map((result) => (result.docs ?? []).filter((item) => item.latitude !== null && item.longitude !== null) ) ); } getLaunchpads(): Observable { return this.http .post>(`${this.baseUrl}/launchpads/query`, { query: {}, options: { pagination: false, populate: [{ path: 'rockets', select: { name: 1 } }] } }) .pipe(map((result) => result.docs ?? [])); } getLandpads(): Observable { return this.http .post>(`${this.baseUrl}/landpads/query`, { query: {}, options: { pagination: false } }) .pipe(map((result) => result.docs ?? [])); } }