BugFix: ERROR [ExceptionsHandler] column "users.areasServed" must appear in the GROUP BY clause or be used in an aggregate function resolved

This commit is contained in:
Andreas Knuth 2024-09-04 18:15:16 +02:00
parent 7807afbad3
commit 9ecc0c2429
7 changed files with 2 additions and 97 deletions

View File

@ -70,13 +70,6 @@ export class UserController {
findTotal(@Body() criteria: UserListingCriteria): Promise<number> {
return this.userService.getUserListingsCount(criteria);
}
@Get('states/all')
async getStates(): Promise<any[]> {
this.logger.info(`Getting all states for users`);
const result = await this.userService.getStates();
this.logger.info(`Found ${result.length} entries`);
return result;
}
@UseGuards(JwtAuthGuard)
@Get('subscriptions/:id')

View File

@ -140,10 +140,4 @@ export class UserService {
throw error;
}
}
async getStates(): Promise<any[]> {
const query = sql`SELECT jsonb_array_elements(${schema.users.areasServed}) ->> 'state' AS state, COUNT(DISTINCT ${schema.users.id}) AS count FROM ${schema.users} GROUP BY state ORDER BY count DESC`;
const result = await this.conn.execute(query);
return result.rows;
}
}

View File

@ -1,66 +1,3 @@
<!-- <div id="sky-line" class="hidden-lg-down"></div>
<div class="search">
<div class="wrapper">
<div class="grid p-4 align-items-center">
<div class="col-2">
<p-dropdown [filter]="true" filterBy="name" [options]="states" [(ngModel)]="criteria.state" optionLabel="name" optionValue="value" [showClear]="true" placeholder="Location" [style]="{ width: '100%' }">
<ng-template let-state pTemplate="item">
<div class="flex align-items-center gap-2">
<div>{{ state.name }} ({{ state.count }})</div>
</div>
</ng-template>
</p-dropdown>
</div>
<div class="col-2">
<p-inputGroup>
<input id="name" type="text" pInputText [(ngModel)]="criteria.name" placeholder="Name" />
<button type="button" pButton icon="pi pi-times" class="p-button-secondary" (click)="reset()"></button>
</p-inputGroup>
</div>
<div class="col-1 col-offset-7">
<p-button label="Refine" (click)="refine()"></p-button>
</div>
</div>
</div>
</div>
<div class="surface-200 h-full">
<div class="wrapper">
<div class="grid">
@for (user of users; track user) {
<div class="col-12 lg:col-6 xl:col-4 p-4 flex flex-column">
<div class="surface-card shadow-2 p-2 flex flex-column flex-grow-1 justify-content-between" style="border-radius: 10px">
<div class="surface-card p-4 flex flex-column align-items-center md:flex-row md:align-items-stretch h-full">
<span>
@if(user.hasProfile){
<img src="{{ env.imageBaseUrl }}/pictures/profile/{{ emailToDirName(user.email) }}.avif?_ts={{ ts }}" class="w-5rem" />
} @else {
<img src="assets/images/person_placeholder.jpg" class="w-5rem" />
}
</span>
<div class="flex flex-column align-items-center md:align-items-stretch ml-4 mt-4 md:mt-0">
<p class="mt-0 mb-3 line-height-3 text-center md:text-left">{{ user.description }}</p>
<span class="text-900 font-medium mb-1 mt-auto">{{ user.firstname }} {{ user.lastname }}</span>
<div class="text-600 text-sm">{{ user.companyName }}</div>
</div>
</div>
<div class="px-4 py-3 text-right flex justify-content-between align-items-center">
@if(user.hasCompanyLogo){
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ emailToDirName(user.email) }}.avif?_ts={{ ts }}" class="rounded-image" />
} @else {
<img src="assets/images/placeholder.png" class="rounded-image" />
}
<button pButton pRipple icon="pi pi-arrow-right" iconPos="right" label="View Full profile" class="p-button-rounded p-button-success" [routerLink]="['/details-user', user.id]"></button>
</div>
</div>
</div>
}
</div>
<div class="mb-2 surface-200 flex align-items-center justify-content-center paginator-bar">
<div class="mx-1 text-color">Total number of Professionals/Brokers: {{ totalRecords }}</div>
<p-paginator (onPageChange)="onPageChange($event)" [first]="first" [rows]="rows" [totalRecords]="totalRecords" [rowsPerPageOptions]="[12, 24, 48]"></p-paginator>
</div>
</div>
</div> -->
<div class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Amanda Taylor -->

View File

@ -31,7 +31,6 @@ export class BrokerListingsComponent {
maxPrice: string;
minPrice: string;
type: string;
states = [];
statesSet = new Set();
state: string;
first: number = 0;
@ -63,10 +62,7 @@ export class BrokerListingsComponent {
}
});
}
async ngOnInit() {
const statesResult = await this.userService.getAllStates();
this.states = statesResult.map(ls => ({ name: this.selectOptions.getState(ls.state as string), value: ls.state, count: ls.count }));
}
async ngOnInit() {}
async init() {
this.search();
}

View File

@ -28,7 +28,6 @@ export class BusinessListingsComponent {
maxPrice: string;
minPrice: string;
type: string;
states = [];
state: string;
totalRecords: number = 0;
ts = new Date().getTime();

View File

@ -30,7 +30,6 @@ export class CommercialPropertyListingsComponent {
maxPrice: string;
minPrice: string;
type: string;
states = [];
statesSet = new Set();
state: string;
totalRecords: number = 0;
@ -59,8 +58,6 @@ export class CommercialPropertyListingsComponent {
}
async ngOnInit() {}
async init() {
const statesResult = await this.listingsService.getAllStates('commercialProperty');
this.states = statesResult.map(ls => ({ name: this.selectOptions.getState(ls.state as string), value: ls.state, count: ls.count }));
this.search();
}
async search() {

View File

@ -2,14 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, lastValueFrom } from 'rxjs';
import { BusinessListing, CommercialPropertyListing } from '../../../../bizmatch-server/src/models/db.model';
import {
BusinessListingCriteria,
CommercialPropertyListingCriteria,
ListingType,
ResponseBusinessListingArray,
ResponseCommercialPropertyListingArray,
StatesResult,
} from '../../../../bizmatch-server/src/models/main.model';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, ListingType, ResponseBusinessListingArray, ResponseCommercialPropertyListingArray } from '../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../environments/environment';
@Injectable({
@ -50,10 +43,6 @@ export class ListingsService {
return await lastValueFrom(this.http.post<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}`, listing));
}
}
async getAllStates(listingsCategory?: 'business' | 'commercialProperty'): Promise<StatesResult[]> {
const result = lastValueFrom(this.http.get<StatesResult[]>(`${this.apiBaseUrl}/bizmatch/listings/business/states/all`));
return result;
}
async deleteBusinessListing(id: string) {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/business/${id}`));
}