Migrate transactions backend calls to promise api

This commit is contained in:
William Brawner 2022-11-10 21:01:12 -07:00
parent ec47fc130d
commit 6cc063f776
9 changed files with 95 additions and 106 deletions

View file

@ -126,7 +126,7 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
date.setMilliseconds(0);
date.setDate(1);
this.twigsService.getTransactions(this.budget.id, null, 5, date)
.subscribe(transactions => this.transactions = <Transaction[]>transactions);
.then(transactions => this.transactions = <Transaction[]>transactions);
}
async getCategories() {

View file

@ -1,11 +1,9 @@
import { Component, OnInit, Input, Inject } from '@angular/core';
import { Component, OnInit, Inject } from '@angular/core';
import { Category } from './category';
import { AppComponent } from '../app.component';
import { Observable } from 'rxjs';
import { TransactionType } from '../transactions/transaction.type';
import { Budget } from '../budgets/budget';
import { ActivatedRoute } from '@angular/router';
import { TWIGS_SERVICE, TwigsService } from '../shared/twigs.service';
import { Transaction } from '../transactions/transaction';
@Component({
selector: 'app-categories',
@ -36,24 +34,28 @@ export class CategoriesComponent implements OnInit {
this.twigsService.getCategories(this.budgetId).then(categories => {
this.categories = categories;
for (const category of this.categories) {
this.getCategoryBalance(category).subscribe(balance => this.categoryBalances.set(category.id, balance));
this.getCategoryBalance(category).then(balance => this.categoryBalances.set(category.id, balance));
}
});
}
getCategoryBalance(category: Category): Observable<number> {
return Observable.create(subscriber => {
this.twigsService.getTransactions(this.budgetId, category.id).subscribe(transactions => {
let balance = 0;
for (const transaction of transactions) {
if (transaction.expense) {
balance -= transaction.amount;
} else {
balance += transaction.amount;
}
getCategoryBalance(category: Category): Promise<number> {
return new Promise(async (resolve, reject) => {
let transactions: Transaction[]
try {
transactions = await this.twigsService.getTransactions(this.budgetId, category.id)
} catch(e) {
reject(e)
}
let balance = 0;
for (const transaction of transactions) {
if (transaction.expense) {
balance -= transaction.amount;
} else {
balance += transaction.amount;
}
subscriber.next(balance);
});
}
resolve(balance);
});
}
}

View file

@ -1,4 +1,4 @@
import { Component, OnInit, Input, OnDestroy, Inject } from '@angular/core';
import { Component, OnInit, Input, Inject } from '@angular/core';
import { Category } from '../category';
import { AppComponent } from 'src/app/app.component';
import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
@ -39,15 +39,13 @@ export class CategoryFormComponent implements OnInit {
);
} else {
// This is an existing category, update it
const updatedCategory: Category = {
...this.currentCategory,
amount: this.currentCategory.amount * 100
}
promise = this.twigsService.updateCategory(
this.currentCategory.id,
{
name: this.currentCategory.title,
description: this.currentCategory.description,
amount: this.currentCategory.amount * 100,
expense: this.currentCategory.expense,
archived: this.currentCategory.archived
}
this.currentCategory
);
}
promise.then(_ => {

View file

@ -1,13 +1,10 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable, pipe, Subscriber } from 'rxjs';
import { User, UserPermission, Permission, AuthToken } from '../users/user';
import { TwigsService } from './twigs.service';
import { Budget } from '../budgets/budget';
import { Category } from '../categories/category';
import { Transaction } from '../transactions/transaction';
import { environment } from '../../environments/environment';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
@ -20,7 +17,6 @@ export class TwigsHttpService implements TwigsService {
private apiUrl = environment.apiUrl;
constructor(
private http: HttpClient,
private storage: Storage
) { }
@ -175,45 +171,41 @@ export class TwigsHttpService implements TwigsService {
}
// Transactions
getTransactions(
async getTransactions(
budgetId?: string,
categoryId?: string,
count?: number,
from?: Date,
to?: Date
): Observable<Transaction[]> {
let httpParams = new HttpParams();
): Promise<Transaction[]> {
const url = new URL(`/api/transactions`, this.apiUrl)
if (budgetId) {
httpParams = httpParams.set('budgetIds', `${budgetId}`);
url.searchParams.set('budgetIds', budgetId);
}
if (categoryId) {
httpParams = httpParams.set('categoryIds', `${categoryId}`);
url.searchParams.set('categoryIds', categoryId);
}
if (from) {
httpParams = httpParams.set('from', from.toISOString());
url.searchParams.set('from', from.toISOString());
}
if (to) {
httpParams = httpParams.set('to', to.toISOString());
url.searchParams.set('to', to.toISOString());
}
const params = { params: httpParams };
return this.http.get<Transaction[]>(`${this.apiUrl}/transactions`, Object.assign(params, this.options))
.pipe(map(transactions => {
transactions.forEach(transaction => {
transaction.date = new Date(transaction.date);
});
return transactions;
}));
const transactions: Transaction[] = await this.request(url, HttpMethod.GET)
transactions.forEach(transaction => {
transaction.date = new Date(transaction.date);
})
return transactions
}
getTransaction(id: string): Observable<Transaction> {
return this.http.get<Transaction>(`${this.apiUrl}/transactions/${id}`, this.options)
.pipe(map(transaction => {
transaction.date = new Date(transaction.date);
return transaction;
}));
async getTransaction(id: string): Promise<Transaction> {
const url = new URL(`/api/transactions/${id}`, this.apiUrl)
const transaction: Transaction = await this.request(url, HttpMethod.GET)
transaction.date = new Date(transaction.date)
return transaction
}
createTransaction(
async createTransaction(
id: string,
budgetId: string,
name: string,
@ -222,8 +214,9 @@ export class TwigsHttpService implements TwigsService {
date: Date,
expense: boolean,
category: string
): Observable<Transaction> {
const params = {
): Promise<Transaction> {
const url = new URL(`/api/transactions`, this.apiUrl)
const body = {
'id': id,
'title': name,
'description': description,
@ -233,15 +226,23 @@ export class TwigsHttpService implements TwigsService {
'categoryId': category,
'budgetId': budgetId
};
return this.http.post<Transaction>(this.apiUrl + '/transactions', params, this.options);
const transaction: Transaction = await this.request(url, HttpMethod.POST, body)
transaction.date = new Date(transaction.date)
return transaction
}
updateTransaction(id: string, changes: object): Observable<Transaction> {
return this.http.put<Transaction>(`${this.apiUrl}/transactions/${id}`, changes, this.options);
async updateTransaction(id: string, transaction: Transaction): Promise<Transaction> {
const body: any = transaction;
body.date = transaction.date.toISOString()
const url = new URL(`/api/transactions/${id}`, this.apiUrl)
const updatedTransaction: Transaction = await this.request(url, HttpMethod.PUT, body)
updatedTransaction.date = new Date(updatedTransaction.date)
return updatedTransaction
}
deleteTransaction(id: string): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/transactions/${id}`, this.options);
deleteTransaction(id: string): Promise<void> {
const url = new URL(`/api/transactions/${id}`, this.apiUrl)
return this.request(url, HttpMethod.DELETE)
}
// Users

View file

@ -1,6 +1,4 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { Observable, Subscriber } from 'rxjs';
import { User, UserPermission } from '../users/user';
import { TwigsService } from './twigs.service';
import { Budget } from '../budgets/budget';
@ -18,7 +16,6 @@ import { randomId } from '../shared/utils';
export class TwigsLocalService implements TwigsService {
constructor(
private http: HttpClient
) { }
private users: User[] = [new User(randomId(), 'test', 'test@example.com')];
@ -203,9 +200,9 @@ export class TwigsLocalService implements TwigsService {
}
// Transactions
getTransactions(budgetId?: string, categoryId?: string, count?: number): Observable<Transaction[]> {
return new Observable(subscriber => {
subscriber.next(this.transactions.filter(transaction => {
getTransactions(budgetId?: string, categoryId?: string, count?: number): Promise<Transaction[]> {
return new Promise((resolve, reject) => {
resolve(this.transactions.filter(transaction => {
let include = true;
if (budgetId) {
include = transaction.budgetId === budgetId;
@ -215,15 +212,11 @@ export class TwigsLocalService implements TwigsService {
}
return include;
}));
subscriber.complete();
});
}
getTransaction(id: string): Observable<Transaction> {
return new Observable(subscriber => {
subscriber.next(this.findById(this.transactions, id));
subscriber.complete();
});
getTransaction(id: string): Promise<Transaction> {
return Promise.resolve(this.findById(this.transactions, id));
}
createTransaction(
@ -235,8 +228,8 @@ export class TwigsLocalService implements TwigsService {
date: Date,
isExpense: boolean,
category: string
): Observable<Transaction> {
return new Observable(subscriber => {
): Promise<Transaction> {
return new Promise((resolve, reject) => {
const transaction = new Transaction();
transaction.title = name;
transaction.description = description;
@ -247,13 +240,12 @@ export class TwigsLocalService implements TwigsService {
transaction.budgetId = budgetId;
transaction.id = randomId();
this.transactions.push(transaction);
subscriber.next(transaction);
subscriber.complete();
resolve(transaction);
});
}
updateTransaction(id: string, changes: object): Observable<Transaction> {
return new Observable(subscriber => {
updateTransaction(id: string, changes: object): Promise<Transaction> {
return new Promise((resolve, reject) => {
const transaction = this.findById(this.transactions, id);
if (transaction) {
const index = this.transactions.indexOf(transaction);
@ -272,23 +264,22 @@ export class TwigsLocalService implements TwigsService {
]
);
this.transactions[index] = transaction;
subscriber.next(transaction);
resolve(transaction);
} else {
subscriber.error('No transaction found for given id');
reject('No transaction found for given id');
}
subscriber.complete();
});
}
deleteTransaction(id: string): Observable<void> {
return new Observable(subscriber => {
deleteTransaction(id: string): Promise<void> {
return new Promise((resolve, reject) => {
const transaction = this.findById(this.transactions, id);
if (transaction) {
const index = this.transactions.indexOf(transaction);
delete this.transactions[index];
subscriber.complete();
resolve();
} else {
subscriber.error('No transaction found for given id');
reject('No transaction found for given id');
}
});
}

View file

@ -1,5 +1,4 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';
import { User, UserPermission } from '../users/user';
import { Budget } from '../budgets/budget';
import { Category } from '../categories/category';
@ -29,7 +28,7 @@ export interface TwigsService {
getCategory(id: string): Promise<Category>;
getCategoryBalance(id: string, from?: Date, to?: Date): Promise<number>;
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Promise<Category>;
updateCategory(id: string, changes: object): Promise<Category>;
updateCategory(id: string, category: Category): Promise<Category>;
deleteCategory(id: string): Promise<void>;
// Transactions
@ -39,8 +38,8 @@ export interface TwigsService {
count?: number,
from?: Date,
to?: Date
): Observable<Transaction[]>;
getTransaction(id: string): Observable<Transaction>;
): Promise<Transaction[]>;
getTransaction(id: string): Promise<Transaction>;
createTransaction(
id: string,
budgetId: string,
@ -50,9 +49,9 @@ export interface TwigsService {
date: Date,
isExpense: boolean,
category: string
): Observable<Transaction>;
updateTransaction(id: string, changes: object): Observable<Transaction>;
deleteTransaction(id: string): Observable<void>;
): Promise<Transaction>;
updateTransaction(id: string, transaction: Transaction): Promise<Transaction>;
deleteTransaction(id: string): Promise<void>;
getProfile(id: string): Promise<User>;
getUsersByUsername(username: string): Promise<User[]>;

View file

@ -62,7 +62,7 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
save(): void {
// The amount will be input as a decimal value so we need to convert it
// to an integer
let observable;
let promise;
this.currentTransaction.date = new Date();
const dateParts = this.transactionDate.split('-');
this.currentTransaction.date.setFullYear(parseInt(dateParts[0], 10));
@ -73,7 +73,7 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
this.currentTransaction.date.setMinutes(parseInt(timeParts[1], 10));
if (this.create) {
// This is a new transaction, save it
observable = this.twigsService.createTransaction(
promise = this.twigsService.createTransaction(
this.currentTransaction.id,
this.budgetId,
this.currentTransaction.title,
@ -85,26 +85,23 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
);
} else {
// This is an existing transaction, update it
observable = this.twigsService.updateTransaction(
const updatedTransaction: Transaction = {
...this.currentTransaction,
amount: Math.round(this.currentTransaction.amount * 100)
}
promise = this.twigsService.updateTransaction(
this.currentTransaction.id,
{
title: this.currentTransaction.title,
description: this.currentTransaction.description,
amount: Math.round(this.currentTransaction.amount * 100),
date: this.currentTransaction.date,
categoryId: this.currentTransaction.categoryId,
expense: this.currentTransaction.expense
}
updatedTransaction
);
}
observable.subscribe(val => {
promise.then(() => {
this.app.goBack();
});
}
delete(): void {
this.twigsService.deleteTransaction(this.currentTransaction.id).subscribe(() => {
this.twigsService.deleteTransaction(this.currentTransaction.id).then(() => {
this.app.goBack();
});
}

View file

@ -25,7 +25,7 @@ export class TransactionDetailsComponent implements OnInit {
getTransaction(): void {
const id = this.route.snapshot.paramMap.get('id');
this.twigsService.getTransaction(id)
.subscribe(transaction => {
.then(transaction => {
transaction.amount /= 100;
this.transaction = transaction;
this.budgetId = transaction.budgetId;

View file

@ -52,7 +52,8 @@ export class TransactionListComponent implements OnInit {
}
}
this.twigsService.getTransactions(this.budgetIds.join(','), this.categoryIds?.join(','), null, from, to).subscribe(transactions => {
this.twigsService.getTransactions(this.budgetIds.join(','), this.categoryIds?.join(','), null, from, to)
.then(transactions => {
this.transactions = transactions;
});
}