Migrate budgets backend calls to promise api

This commit is contained in:
William Brawner 2022-11-09 03:16:23 +00:00
parent e11ffb741f
commit 170214c1ca
8 changed files with 82 additions and 137 deletions

View file

@ -3,6 +3,7 @@ import { Budget } from '../budget';
import { AppComponent } from 'src/app/app.component'; import { AppComponent } from 'src/app/app.component';
import { User, UserPermission, Permission } from 'src/app/users/user'; import { User, UserPermission, Permission } from 'src/app/users/user';
import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service'; import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
import { Router } from '@angular/router';
@Component({ @Component({
selector: 'app-add-edit-budget', selector: 'app-add-edit-budget',
@ -19,6 +20,7 @@ export class AddEditBudgetComponent {
constructor( constructor(
private app: AppComponent, private app: AppComponent,
private router: Router,
@Inject(TWIGS_SERVICE) private twigsService: TwigsService, @Inject(TWIGS_SERVICE) private twigsService: TwigsService,
) { ) {
this.app.setTitle(this.title) this.app.setTitle(this.title)
@ -27,11 +29,11 @@ export class AddEditBudgetComponent {
} }
save(): void { save(): void {
let observable; let promise: Promise<Budget>;
this.isLoading = true; this.isLoading = true;
if (this.create) { if (this.create) {
// This is a new budget, save it // This is a new budget, save it
observable = this.twigsService.createBudget( promise = this.twigsService.createBudget(
this.budget.id, this.budget.id,
this.budget.name, this.budget.name,
this.budget.description, this.budget.description,
@ -39,10 +41,10 @@ export class AddEditBudgetComponent {
); );
} else { } else {
// This is an existing budget, update it // This is an existing budget, update it
observable = this.twigsService.updateBudget(this.budget.id, this.budget); promise = this.twigsService.updateBudget(this.budget.id, this.budget);
} }
// TODO: Check if it was actually successful or not // TODO: Check if it was actually successful or not
observable.subscribe(val => { promise.then(_ => {
this.app.goBack(); this.app.goBack();
}); });
} }
@ -50,8 +52,8 @@ export class AddEditBudgetComponent {
delete(): void { delete(): void {
this.isLoading = true; this.isLoading = true;
this.twigsService.deleteBudget(this.budget.id) this.twigsService.deleteBudget(this.budget.id)
.subscribe(() => { .then(() => {
this.app.goBack(); this.router.navigateByUrl("/budgets");
}); });
} }

View file

@ -82,7 +82,7 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
getBudget() { getBudget() {
const id = this.route.snapshot.paramMap.get('id'); const id = this.route.snapshot.paramMap.get('id');
this.twigsService.getBudget(id) this.twigsService.getBudget(id)
.subscribe(budget => { .then(budget => {
this.app.setTitle(budget.name) this.app.setTitle(budget.name)
this.budget = budget; this.budget = budget;
this.getBalance(); this.getBalance();
@ -115,9 +115,10 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
getBalance(): void { getBalance(): void {
const id = this.route.snapshot.paramMap.get('id'); const id = this.route.snapshot.paramMap.get('id');
this.twigsService.getBudgetBalance(id, this.from, this.to).subscribe(balance => { this.twigsService.getBudgetBalance(id, this.from, this.to)
this.budgetBalance = balance; .then(balance => {
}); this.budgetBalance = balance;
});
} }
getTransactions(): void { getTransactions(): void {

View file

@ -16,7 +16,7 @@ export class BudgetsComponent implements OnInit {
constructor( constructor(
private app: AppComponent, private app: AppComponent,
@Inject(TWIGS_SERVICE) private twigsService: TwigsService, @Inject(TWIGS_SERVICE) private twigsService: TwigsService,
) { } ) { }
ngOnInit() { ngOnInit() {
@ -32,16 +32,17 @@ export class BudgetsComponent implements OnInit {
this.app.setTitle('Budgets') this.app.setTitle('Budgets')
this.loggedIn = true; this.loggedIn = true;
this.loading = true; this.loading = true;
this.twigsService.getBudgets().subscribe( this.twigsService.getBudgets()
budgets => { .then(
console.log(budgets) budgets => {
this.budgets = budgets; console.log(budgets)
this.budgets = budgets;
this.loading = false;
})
.catch(error => {
console.log(error)
this.loading = false; this.loading = false;
}, });
error => {
this.loading = false;
}
);
}, },
error => { error => {
this.loading = false; this.loading = false;

View file

@ -20,7 +20,7 @@ export class EditBudgetComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
const id = this.route.snapshot.paramMap.get('id'); const id = this.route.snapshot.paramMap.get('id');
this.twigsService.getBudget(id) this.twigsService.getBudget(id)
.subscribe(budget => { .then(budget => {
this.budget = budget; this.budget = budget;
}); });
} }

View file

@ -18,7 +18,6 @@ export class TwigsHttpService implements TwigsService {
withCredentials: true withCredentials: true
}; };
private apiUrl = environment.apiUrl; private apiUrl = environment.apiUrl;
private budgets: BehaviorSubject<Budget[]> = new BehaviorSubject(null);
constructor( constructor(
private http: HttpClient, private http: HttpClient,
@ -55,57 +54,30 @@ export class TwigsHttpService implements TwigsService {
} }
// Budgets // Budgets
getBudgets(): Observable<Budget[]> { getBudgets(): Promise<Budget[]> {
this.http.get<Budget[]>(this.apiUrl + '/budgets', this.options) const url = new URL('/api/budgets', this.apiUrl)
.subscribe(budgets => { return this.request(url, HttpMethod.GET)
this.budgets.next(budgets);
});
return this.budgets;
} }
getBudgetBalance( getBudgetBalance(
id: string, id: string,
from?: Date, from?: Date,
to?: Date to?: Date
): Observable<number> { ): Promise<number> {
let httpParams = new HttpParams(); const url = new URL('/api/transactions/sum')
url.searchParams.set('budgetId', id)
if (from) { if (from) {
httpParams = httpParams.set('from', from.toISOString()); url.searchParams.set('from', from.toISOString());
} }
if (to) { if (to) {
httpParams = httpParams.set('to', to.toISOString()); url.searchParams.set('to', to.toISOString());
} }
const params = { params: httpParams }; return this.request(url, HttpMethod.GET).then((res: any) => res.balance)
return this.http.get<any>(`${this.apiUrl}/transactions/sum?budgetId=${id}`, { ...this.options, ...params })
.pipe(map(obj => obj.balance));
} }
getBudget(id: string): Observable<Budget> { getBudget(id: string): Promise<Budget> {
return new Observable(emitter => { const url = new URL(`/api/budgets/${id}`, this.apiUrl)
var cachedBudget: Budget return this.request(url, HttpMethod.GET)
if (this.budgets.value) {
cachedBudget = this.budgets.value.find(budget => {
return budget.id === id;
});
}
if (cachedBudget) {
emitter.next(cachedBudget);
emitter.complete();
} else {
this.http.get<Budget>(`${this.apiUrl}/budgets/${id}`, this.options)
.subscribe(budget => {
var oldBudgets = JSON.parse(JSON.stringify(this.budgets.value));
if (!oldBudgets) {
oldBudgets = [];
}
oldBudgets.push(budget);
oldBudgets.sort();
this.budgets.next(oldBudgets);
emitter.next(budget);
emitter.complete();
})
}
})
} }
createBudget( createBudget(
@ -113,8 +85,9 @@ export class TwigsHttpService implements TwigsService {
name: string, name: string,
description: string, description: string,
users: UserPermission[], users: UserPermission[],
): Observable<Budget> { ): Promise<Budget> {
const params = { const url = new URL('/api/budgets', this.apiUrl)
const body = {
'id': id, 'id': id,
'name': name, 'name': name,
'description': description, 'description': description,
@ -125,19 +98,12 @@ export class TwigsHttpService implements TwigsService {
}; };
}) })
}; };
return this.http.post<Budget>(this.apiUrl + '/budgets', params, this.options) return this.request(url, HttpMethod.POST, body)
.pipe(map(budget => {
var updatedBudgets = JSON.parse(JSON.stringify(this.budgets.value));
updatedBudgets.push(budget);
updatedBudgets.sort();
this.budgets.next(updatedBudgets);
return budget
}))
} }
updateBudget(id: string, changes: object): Observable<Budget> { updateBudget(id: string, budget: Budget): Promise<Budget> {
let budget = changes as Budget; const url = new URL(`/api/budgets/${id}`, this.apiUrl)
const params = { const body = {
'name': budget.name, 'name': budget.name,
'description': budget.description, 'description': budget.description,
'users': budget.users.map(userPermission => { 'users': budget.users.map(userPermission => {
@ -147,32 +113,12 @@ export class TwigsHttpService implements TwigsService {
}; };
}) })
}; };
return this.http.put<Budget>(`${this.apiUrl}/budgets/${id}`, params, this.options) return this.request(url, HttpMethod.PUT, body)
.pipe(map(budget => {
var updatedBudgets: Budget[] = JSON.parse(JSON.stringify(this.budgets.value));
var index = updatedBudgets.findIndex(oldBudget => oldBudget.id === id);
if (index > -1) {
updatedBudgets.splice(index, 1);
}
updatedBudgets.push(budget);
updatedBudgets.sort();
this.budgets.next(updatedBudgets);
return budget
}));
} }
deleteBudget(id: String): Observable<void> { deleteBudget(id: String): Promise<void> {
return this.http.delete<void>(`${this.apiUrl}/budgets/${id}`, this.options) const url = new URL(`/api/budgets/${id}`, this.apiUrl)
.pipe(map(() => { return this.request(url, HttpMethod.DELETE)
var updatedBudgets: Budget[] = JSON.parse(JSON.stringify(this.budgets.value));
var index = updatedBudgets.findIndex(oldBudget => oldBudget.id === id);
if (index > -1) {
updatedBudgets.splice(index, 1);
}
updatedBudgets.sort();
this.budgets.next(updatedBudgets);
return;
}));
} }
// Categories // Categories
@ -328,6 +274,10 @@ export class TwigsHttpService implements TwigsService {
body: jsonBody body: jsonBody
}) })
if (res.status === 204) {
// No content
return
}
return res.json() return res.json()
} }
} }

View file

@ -56,31 +56,24 @@ export class TwigsLocalService implements TwigsService {
} }
// Budgets // Budgets
getBudgets(): Observable<Budget[]> { getBudgets(): Promise<Budget[]> {
return new Observable(subscriber => { return Promise.resolve(this.budgets)
subscriber.next(this.budgets);
subscriber.complete();
});
} }
getBudgetBalance(id: string, from?: Date, to?: Date): Observable<number> { getBudgetBalance(id: string, from?: Date, to?: Date): Promise<number> {
return new Observable(emitter => { return Promise.resolve(200)
emitter.next(200);
emitter.complete()
})
} }
getBudget(id: string): Observable<Budget> { getBudget(id: string): Promise<Budget> {
return new Observable(subscriber => { return new Promise((resolve, reject) => {
const budget = this.budgets.filter(it => { const budget = this.budgets.filter(it => {
return it.id === id; return it.id === id;
})[0]; })[0];
if (budget) { if (budget) {
subscriber.next(budget); resolve(budget);
} else { } else {
subscriber.error('No budget found for given id'); reject('No budget found for given id');
} }
subscriber.complete();
}); });
} }
@ -89,21 +82,20 @@ export class TwigsLocalService implements TwigsService {
name: string, name: string,
description: string, description: string,
users: UserPermission[], users: UserPermission[],
): Observable<Budget> { ): Promise<Budget> {
return new Observable(subscriber => { return new Promise((resolve, reject) => {
const budget = new Budget(); const budget = new Budget();
budget.name = name; budget.name = name;
budget.description = description; budget.description = description;
budget.users = users; budget.users = users;
budget.id = id; budget.id = id;
this.budgets.push(budget); this.budgets.push(budget);
subscriber.next(budget); resolve(budget);
subscriber.complete();
}); });
} }
updateBudget(id: string, changes: object): Observable<Budget> { updateBudget(id: string, budget: Budget): Promise<Budget> {
return new Observable(subscriber => { return new Promise((resolve, reject) => {
const budget = this.budgets.filter(it => { const budget = this.budgets.filter(it => {
return it.id === id; return it.id === id;
})[0]; })[0];
@ -111,7 +103,7 @@ export class TwigsLocalService implements TwigsService {
const index = this.budgets.indexOf(budget); const index = this.budgets.indexOf(budget);
this.updateValues( this.updateValues(
budget, budget,
changes, budget,
[ [
'name', 'name',
'description', 'description',
@ -119,25 +111,24 @@ export class TwigsLocalService implements TwigsService {
] ]
); );
this.budgets[index] = budget; this.budgets[index] = budget;
subscriber.next(budget); resolve(budget);
} else { } else {
subscriber.error('No budget found for given id'); reject('No budget found for given id');
} }
subscriber.complete();
}); });
} }
deleteBudget(id: string): Observable<void> { deleteBudget(id: string): Promise<void> {
return new Observable(subscriber => { return new Promise((resolve, reject) => {
const budget = this.budgets.filter(it => { const budget = this.budgets.filter(it => {
return budget.id === id; return budget.id === id;
})[0]; })[0];
if (budget) { if (budget) {
const index = this.budgets.indexOf(budget); const index = this.budgets.indexOf(budget);
delete this.budgets[index]; delete this.budgets[index];
subscriber.complete(); resolve();
} else { } else {
subscriber.error('No budget found for given id'); reject('No budget found for given id');
} }
}); });
} }

View file

@ -12,17 +12,17 @@ export interface TwigsService {
logout(): Promise<void>; logout(): Promise<void>;
// Budgets // Budgets
getBudgets(): Observable<Budget[]>; getBudgets(): Promise<Budget[]>;
getBudget(id: string): Observable<Budget>; getBudget(id: string): Promise<Budget>;
getBudgetBalance(id: string, from?: Date, to?: Date): Observable<number>; getBudgetBalance(id: string, from?: Date, to?: Date): Promise<number>;
createBudget( createBudget(
id: string, id: string,
name: string, name: string,
description: string, description: string,
users: UserPermission[], users: UserPermission[],
): Observable<Budget>; ): Promise<Budget>;
updateBudget(id: string, changes: object): Observable<Budget>; updateBudget(id: string, budget: Budget): Promise<Budget>;
deleteBudget(id: string): Observable<void>; deleteBudget(id: string): Promise<void>;
// Categories // Categories
getCategories(budgetId?: string, count?: number): Observable<Category[]>; getCategories(budgetId?: string, count?: number): Observable<Category[]>;

View file

@ -29,8 +29,8 @@ export class UserPermission {
} }
export enum Permission { export enum Permission {
READ, READ = "READ",
WRITE, WRITE = "WRITE",
MANAGE, MANAGE = "MANAGE",
OWNER OWNER = "OWNER"
} }