Migrate categories backend calls to promise api
This commit is contained in:
parent
87092be0f9
commit
ec47fc130d
9 changed files with 92 additions and 105 deletions
|
@ -4,8 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { AppComponent } from 'src/app/app.component';
|
import { AppComponent } from 'src/app/app.component';
|
||||||
import { Transaction } from 'src/app/transactions/transaction';
|
import { Transaction } from 'src/app/transactions/transaction';
|
||||||
import { Category } from 'src/app/categories/category';
|
import { Category } from 'src/app/categories/category';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
// import { Label } from 'ng2-charts';
|
|
||||||
import { ChartDataset } from 'chart.js';
|
import { ChartDataset } from 'chart.js';
|
||||||
import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
|
import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
|
||||||
import { Actionable } from '../../shared/actionable';
|
import { Actionable } from '../../shared/actionable';
|
||||||
|
@ -16,7 +14,6 @@ import { Actionable } from '../../shared/actionable';
|
||||||
styleUrls: ['./budget-details.component.css']
|
styleUrls: ['./budget-details.component.css']
|
||||||
})
|
})
|
||||||
export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
|
export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
|
||||||
|
|
||||||
budget: Budget;
|
budget: Budget;
|
||||||
public budgetBalance: number;
|
public budgetBalance: number;
|
||||||
public transactions: Transaction[];
|
public transactions: Transaction[];
|
||||||
|
@ -132,43 +129,38 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
|
||||||
.subscribe(transactions => this.transactions = <Transaction[]>transactions);
|
.subscribe(transactions => this.transactions = <Transaction[]>transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategories(): void {
|
async getCategories() {
|
||||||
this.twigsService.getCategories(this.budget.id).subscribe(categories => {
|
const categories = await this.twigsService.getCategories(this.budget.id)
|
||||||
const categoryBalances = new Map<string, number>();
|
const categoryBalances = new Map<string, number>();
|
||||||
let categoryBalancesCount = 0;
|
let categoryBalancesCount = 0;
|
||||||
console.log(categories);
|
for (const category of categories) {
|
||||||
for (const category of categories) {
|
if (category.expense) {
|
||||||
if (category.expense) {
|
this.expenses.push(category);
|
||||||
this.expenses.push(category);
|
this.expectedExpenses += category.amount;
|
||||||
this.expectedExpenses += category.amount;
|
} else {
|
||||||
} else {
|
this.income.push(category);
|
||||||
this.income.push(category);
|
this.expectedIncome += category.amount;
|
||||||
this.expectedIncome += category.amount;
|
|
||||||
}
|
|
||||||
this.twigsService.getCategoryBalance(category.id, this.from, this.to).subscribe(
|
|
||||||
balance => {
|
|
||||||
console.log(balance);
|
|
||||||
if (category.expense) {
|
|
||||||
this.actualExpenses += balance * -1;
|
|
||||||
} else {
|
|
||||||
this.actualIncome += balance;
|
|
||||||
}
|
|
||||||
categoryBalances.set(category.id, balance);
|
|
||||||
categoryBalancesCount++;
|
|
||||||
},
|
|
||||||
error => { categoryBalancesCount++; },
|
|
||||||
() => {
|
|
||||||
// This weird workaround is to force the OnChanges callback to be fired.
|
|
||||||
// Angular needs the reference to the object to change in order for it to
|
|
||||||
// work.
|
|
||||||
if (categoryBalancesCount === categories.length) {
|
|
||||||
this.categoryBalances = categoryBalances;
|
|
||||||
this.updateBarChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
try {
|
||||||
|
const balance = await this.twigsService.getCategoryBalance(category.id, this.from, this.to)
|
||||||
|
console.log(balance);
|
||||||
|
if (category.expense) {
|
||||||
|
this.actualExpenses += balance * -1;
|
||||||
|
} else {
|
||||||
|
this.actualIncome += balance;
|
||||||
|
}
|
||||||
|
categoryBalances.set(category.id, balance);
|
||||||
|
if (categoryBalancesCount === categories.length - 1) {
|
||||||
|
// This weird workaround is to force the OnChanges callback to be fired.
|
||||||
|
// Angular needs the reference to the object to change in order for it to
|
||||||
|
// work.
|
||||||
|
this.categoryBalances = categoryBalances;
|
||||||
|
this.updateBarChart();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
categoryBalancesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doAction(): void {
|
doAction(): void {
|
||||||
|
|
|
@ -33,7 +33,7 @@ export class CategoriesComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategories(): void {
|
getCategories(): void {
|
||||||
this.twigsService.getCategories(this.budgetId).subscribe(categories => {
|
this.twigsService.getCategories(this.budgetId).then(categories => {
|
||||||
this.categories = categories;
|
this.categories = categories;
|
||||||
for (const category of this.categories) {
|
for (const category of this.categories) {
|
||||||
this.getCategoryBalance(category).subscribe(balance => this.categoryBalances.set(category.id, balance));
|
this.getCategoryBalance(category).subscribe(balance => this.categoryBalances.set(category.id, balance));
|
||||||
|
|
|
@ -45,7 +45,7 @@ export class CategoryDetailsComponent implements OnInit, OnDestroy, Actionable {
|
||||||
getCategory(): void {
|
getCategory(): void {
|
||||||
const id = this.route.snapshot.paramMap.get('id');
|
const id = this.route.snapshot.paramMap.get('id');
|
||||||
this.twigsService.getCategory(id)
|
this.twigsService.getCategory(id)
|
||||||
.subscribe(category => {
|
.then(category => {
|
||||||
category.amount /= 100;
|
category.amount /= 100;
|
||||||
this.app.setTitle(category.title)
|
this.app.setTitle(category.title)
|
||||||
this.category = category;
|
this.category = category;
|
||||||
|
|
|
@ -26,10 +26,10 @@ export class CategoryFormComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): void {
|
save(): void {
|
||||||
let observable;
|
let promise;
|
||||||
if (this.create) {
|
if (this.create) {
|
||||||
// This is a new category, save it
|
// This is a new category, save it
|
||||||
observable = this.twigsService.createCategory(
|
promise = this.twigsService.createCategory(
|
||||||
this.currentCategory.id,
|
this.currentCategory.id,
|
||||||
this.budgetId,
|
this.budgetId,
|
||||||
this.currentCategory.title,
|
this.currentCategory.title,
|
||||||
|
@ -39,7 +39,7 @@ export class CategoryFormComponent implements OnInit {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// This is an existing category, update it
|
// This is an existing category, update it
|
||||||
observable = this.twigsService.updateCategory(
|
promise = this.twigsService.updateCategory(
|
||||||
this.currentCategory.id,
|
this.currentCategory.id,
|
||||||
{
|
{
|
||||||
name: this.currentCategory.title,
|
name: this.currentCategory.title,
|
||||||
|
@ -50,13 +50,13 @@ export class CategoryFormComponent implements OnInit {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
observable.subscribe(val => {
|
promise.then(_ => {
|
||||||
this.app.goBack();
|
this.app.goBack();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(): void {
|
delete(): void {
|
||||||
this.twigsService.deleteCategory(this.currentCategory.id).subscribe(() => {
|
this.twigsService.deleteCategory(this.currentCategory.id).then(() => {
|
||||||
this.app.goBack();
|
this.app.goBack();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export class EditCategoryComponent implements OnInit {
|
||||||
getCategory(): void {
|
getCategory(): void {
|
||||||
const id = this.route.snapshot.paramMap.get('id');
|
const id = this.route.snapshot.paramMap.get('id');
|
||||||
this.twigsService.getCategory(id)
|
this.twigsService.getCategory(id)
|
||||||
.subscribe(category => {
|
.then(category => {
|
||||||
category.amount /= 100;
|
category.amount /= 100;
|
||||||
this.app.setTitle(category.title)
|
this.app.setTitle(category.title)
|
||||||
this.category = category;
|
this.category = category;
|
||||||
|
|
|
@ -122,38 +122,38 @@ export class TwigsHttpService implements TwigsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Categories
|
// Categories
|
||||||
getCategories(budgetId: string, count?: number): Observable<Category[]> {
|
getCategories(budgetId: string, count?: number): Promise<Category[]> {
|
||||||
const params = {
|
const url = new URL(`/api/categories`, this.apiUrl)
|
||||||
params: new HttpParams()
|
url.searchParams.set('budgetIds', budgetId)
|
||||||
.set('budgetIds', `${budgetId}`)
|
url.searchParams.set('archived', 'false')
|
||||||
.set('archived', false)
|
return this.request(url, HttpMethod.GET);
|
||||||
};
|
|
||||||
return this.http.get<Category[]>(`${this.apiUrl}/categories`, Object.assign(params, this.options));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategory(id: string): Observable<Category> {
|
getCategory(id: string): Promise<Category> {
|
||||||
return this.http.get<Category>(`${this.apiUrl}/categories/${id}`, this.options);
|
const url = new URL(`/api/categories/${id}`, this.apiUrl)
|
||||||
|
return this.request(url, HttpMethod.GET);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryBalance(
|
async getCategoryBalance(
|
||||||
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`, this.apiUrl)
|
||||||
|
url.searchParams.set('categoryId', 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 };
|
const res: any = await this.request(url, HttpMethod.GET);
|
||||||
return this.http.get<any>(`${this.apiUrl}/transactions/sum?categoryId=${id}`, { ...this.options, ...params })
|
return res.balance;
|
||||||
.pipe(map(obj => obj.balance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Observable<Category> {
|
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Promise<Category> {
|
||||||
const params = {
|
const url = new URL(`/api/categories`, this.apiUrl)
|
||||||
|
const body = {
|
||||||
'id': id,
|
'id': id,
|
||||||
'title': name,
|
'title': name,
|
||||||
'description': description,
|
'description': description,
|
||||||
|
@ -161,15 +161,17 @@ export class TwigsHttpService implements TwigsService {
|
||||||
'expense': isExpense,
|
'expense': isExpense,
|
||||||
'budgetId': budgetId
|
'budgetId': budgetId
|
||||||
};
|
};
|
||||||
return this.http.post<Category>(this.apiUrl + '/categories', params, this.options);
|
return this.request(url, HttpMethod.POST, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCategory(id: string, changes: object): Observable<Category> {
|
updateCategory(id: string, changes: object): Promise<Category> {
|
||||||
return this.http.put<Category>(`${this.apiUrl}/categories/${id}`, changes, this.options);
|
const url = new URL(`/api/categories/${id}`, this.apiUrl)
|
||||||
|
return this.request(url, HttpMethod.PUT, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteCategory(id: string): Observable<void> {
|
deleteCategory(id: string): Promise<void> {
|
||||||
return this.http.delete<void>(`${this.apiUrl}/categories/${id}`, this.options);
|
const url = new URL(`/api/categories/${id}`, this.apiUrl)
|
||||||
|
return this.request(url, HttpMethod.DELETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transactions
|
// Transactions
|
||||||
|
|
|
@ -134,31 +134,26 @@ export class TwigsLocalService implements TwigsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Categories
|
// Categories
|
||||||
getCategories(budgetId: string, count?: number): Observable<Category[]> {
|
getCategories(budgetId: string, count?: number): Promise<Category[]> {
|
||||||
return new Observable(subscriber => {
|
return new Promise((resolve, reject) => {
|
||||||
subscriber.next(this.categories.filter(category => {
|
resolve(this.categories.filter(category => {
|
||||||
return category.budgetId === budgetId;
|
return category.budgetId === budgetId;
|
||||||
}));
|
}));
|
||||||
subscriber.complete();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategory(id: string): Observable<Category> {
|
getCategory(id: string): Promise<Category> {
|
||||||
return new Observable(subscriber => {
|
return new Promise((resolve, reject) => {
|
||||||
subscriber.next(this.findById(this.categories, id));
|
resolve(this.findById(this.categories, id));
|
||||||
subscriber.complete();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryBalance(id: string, from?: Date, to?: Date): Observable<number> {
|
getCategoryBalance(id: string, from?: Date, to?: Date): Promise<number> {
|
||||||
return new Observable(emitter => {
|
return Promise.resolve(20);
|
||||||
emitter.next(20);
|
|
||||||
emitter.complete()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Observable<Category> {
|
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Promise<Category> {
|
||||||
return Observable.create(subscriber => {
|
return new Promise((resolve, reject) => {
|
||||||
const category = new Category();
|
const category = new Category();
|
||||||
category.title = name;
|
category.title = name;
|
||||||
category.description = description;
|
category.description = description;
|
||||||
|
@ -167,13 +162,12 @@ export class TwigsLocalService implements TwigsService {
|
||||||
category.budgetId = budgetId;
|
category.budgetId = budgetId;
|
||||||
category.id = id;
|
category.id = id;
|
||||||
this.categories.push(category);
|
this.categories.push(category);
|
||||||
subscriber.next(category);
|
resolve(category);
|
||||||
subscriber.complete();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCategory(id: string, changes: object): Observable<Category> {
|
updateCategory(id: string, changes: object): Promise<Category> {
|
||||||
return new Observable(subscriber => {
|
return new Promise((resolve, reject) => {
|
||||||
const category = this.findById(this.categories, id);
|
const category = this.findById(this.categories, id);
|
||||||
if (category) {
|
if (category) {
|
||||||
const index = this.categories.indexOf(category);
|
const index = this.categories.indexOf(category);
|
||||||
|
@ -188,23 +182,22 @@ export class TwigsLocalService implements TwigsService {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
this.categories[index] = category;
|
this.categories[index] = category;
|
||||||
subscriber.next(category);
|
resolve(category);
|
||||||
} else {
|
} else {
|
||||||
subscriber.error('No category found for given id');
|
reject('No category found for given id');
|
||||||
}
|
}
|
||||||
subscriber.complete();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteCategory(id: string): Observable<void> {
|
deleteCategory(id: string): Promise<void> {
|
||||||
return new Observable(subscriber => {
|
return new Promise((resolve, reject) => {
|
||||||
const category = this.findById(this.categories, id);
|
const category = this.findById(this.categories, id);
|
||||||
if (category) {
|
if (category) {
|
||||||
const index = this.categories.indexOf(category);
|
const index = this.categories.indexOf(category);
|
||||||
delete this.transactions[index];
|
delete this.transactions[index];
|
||||||
subscriber.complete();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
subscriber.error('No category found for given id');
|
reject('No category found for given id');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,12 @@ export interface TwigsService {
|
||||||
deleteBudget(id: string): Promise<void>;
|
deleteBudget(id: string): Promise<void>;
|
||||||
|
|
||||||
// Categories
|
// Categories
|
||||||
getCategories(budgetId?: string, count?: number): Observable<Category[]>;
|
getCategories(budgetId?: string, count?: number): Promise<Category[]>;
|
||||||
getCategory(id: string): Observable<Category>;
|
getCategory(id: string): Promise<Category>;
|
||||||
getCategoryBalance(id: string, from?: Date, to?: Date): Observable<number>;
|
getCategoryBalance(id: string, from?: Date, to?: Date): Promise<number>;
|
||||||
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Observable<Category>;
|
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Promise<Category>;
|
||||||
updateCategory(id: string, changes: object): Observable<Category>;
|
updateCategory(id: string, changes: object): Promise<Category>;
|
||||||
deleteCategory(id: string): Observable<void>;
|
deleteCategory(id: string): Promise<void>;
|
||||||
|
|
||||||
// Transactions
|
// Transactions
|
||||||
getTransactions(
|
getTransactions(
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
updateCategories(change: MatRadioChange) {
|
updateCategories(change: MatRadioChange) {
|
||||||
this.twigsService.getCategories(this.budgetId)
|
this.twigsService.getCategories(this.budgetId)
|
||||||
.subscribe(newCategories => {
|
.then(newCategories => {
|
||||||
this.categories = newCategories.filter(category => category.expense === change.value)
|
this.categories = newCategories.filter(category => category.expense === change.value)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue