Migrate transactions backend calls to promise api
This commit is contained in:
parent
ec47fc130d
commit
6cc063f776
9 changed files with 95 additions and 106 deletions
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(_ => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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[]>;
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue