Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for observables to withDataService #88

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FlightService } from '../shared/flight.service';
import { FlightService, FlightServiceRXJS } from '../shared/flight.service';

import { signalStore } from '@ngrx/signals';

Expand All @@ -20,3 +20,14 @@ export const SimpleFlightBookingStore = signalStore(
}),
withUndoRedo()
);

export const SimpleFlightBookingStoreWithObservables = signalStore(
{ providedIn: 'root' },
withCallState(),
withEntities<Flight>(),
withDataService({
dataServiceType: FlightServiceRXJS,
filter: { from: 'Paris', to: 'New York' },
}),
withUndoRedo(),
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
import { ChangeDetectionStrategy } from '@angular/core';
import { RouterLink } from '@angular/router';
import { FlightCardComponent } from '../shared/flight-card.component';
import { SimpleFlightBookingStore } from './flight-booking-simple.store';
import { SimpleFlightBookingStore, SimpleFlightBookingStoreWithObservables } from './flight-booking-simple.store';
import { MatTableModule } from '@angular/material/table';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
Expand All @@ -31,7 +31,8 @@ import { MatButtonModule } from '@angular/material/button';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FlightSearchSimpleComponent {
private store = inject(SimpleFlightBookingStore);
// private store = inject(SimpleFlightBookingStore);
private store = inject(SimpleFlightBookingStoreWithObservables); // TODO - differentiate these in more nuanced way than comment in/out

from = this.store.filter.from;
to = this.store.filter.to;
Expand Down
75 changes: 73 additions & 2 deletions apps/demo/src/app/shared/flight.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, firstValueFrom } from 'rxjs';
import { inject, Injectable } from '@angular/core';
import { Observable, firstValueFrom, catchError, of, pipe } from 'rxjs';
import { EntityId } from '@ngrx/signals/entities';
import { DataService } from '@angular-architects/ngrx-toolkit';
import { Flight } from './flight';
Expand Down Expand Up @@ -72,3 +72,74 @@ export class FlightService implements DataService<Flight, FlightFilter> {
return this.http.delete<void>(url);
}
}

@Injectable({
providedIn: 'root'
})
export class FlightServiceRXJS implements DataService<Flight, FlightFilter> {
private baseUrl = `https://demo.angulararchitects.io/api`;
private http = inject(HttpClient);

loadById(id: EntityId): Observable<Flight> {
return this.findById('' + id)
.pipe(catchError((_) => of<Flight>()));
}

create(entity: Flight): Observable<Flight> {
entity.id = 0;
return this.save(entity)
.pipe(catchError((_) => of<Flight>()));
}

update(entity: Flight): Observable<Flight> {
return this.save(entity)
.pipe(catchError((_) => of<Flight>()));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
updateAll(entity: Flight[]): Observable<Flight[]> {
throw new Error('updateAll method not implemented.');
}

delete(entity: Flight): Observable<void> {
return this.remove(entity)
.pipe(catchError((_) => of<void>()));
}

load(filter: FlightFilter): Observable<Flight[]> {
return this.find(filter.from, filter.to)
.pipe(catchError((_) => of<Flight[]>([])));
}

private find(
from: string,
to: string,
urgent = false
): Observable<Flight[]> {
let url = [this.baseUrl, 'flight'].join('/');

if (urgent) {
url = [this.baseUrl, 'error?code=403'].join('/');
}

const params = new HttpParams().set('from', from).set('to', to);
const headers = new HttpHeaders().set('Accept', 'application/json');
return this.http.get<Flight[]>(url, { params, headers });
}

private findById(id: string): Observable<Flight> {
const reqObj = { params: new HttpParams().set('id', id) };
const url = [this.baseUrl, 'flight'].join('/');
return this.http.get<Flight>(url, reqObj);
}

private save(flight: Flight): Observable<Flight> {
const url = [this.baseUrl, 'flight'].join('/');
return this.http.post<Flight>(url, flight);
}

private remove(flight: Flight): Observable<void> {
const url = [this.baseUrl, 'flight', flight.id].join('/');
return this.http.delete<void>(url);
}
}
Loading
Loading