From cd757382108a1943a21ef2001f462024f748ead8 Mon Sep 17 00:00:00 2001 From: trivernis Date: Thu, 16 Jan 2020 10:40:58 +0100 Subject: [PATCH] Refactor Search Service - Move the request part to the service - Switch to @angular/common/http because @angular/http is deprecated --- src/app/components/search/search.component.ts | 16 +-- src/app/models/interfaces/IGroup.ts | 20 +++ src/app/models/interfaces/ISearchResult.ts | 12 ++ src/app/models/interfaces/IUser.ts | 36 +++++ src/app/services/base.service.ts | 16 +++ src/app/services/search/search.service.ts | 130 +++++++++++------- tslint.json | 2 +- 7 files changed, 175 insertions(+), 57 deletions(-) create mode 100644 src/app/models/interfaces/IGroup.ts create mode 100644 src/app/models/interfaces/ISearchResult.ts create mode 100644 src/app/models/interfaces/IUser.ts create mode 100644 src/app/services/base.service.ts diff --git a/src/app/components/search/search.component.ts b/src/app/components/search/search.component.ts index 093471c..dd87acc 100644 --- a/src/app/components/search/search.component.ts +++ b/src/app/components/search/search.component.ts @@ -18,13 +18,12 @@ export class SearchComponent implements OnInit { searchValue = ' '; category = 'user'; user: User; - foundUsers: Array = new Array(); - foundGroups: Array = new Array(); + foundUsers: User[] = []; + foundGroups: GroupInfo[] = []; constructor( private searchService: SearchService, private requestService: RequestService, - private http: Http, private router: Router, private data: DatasharingService) { } ngOnInit() { @@ -46,19 +45,16 @@ export class SearchComponent implements OnInit { this.loading = true; this.findUser(searchWord); } else if (this.category === 'groupe') { - // this.findUserByHandle(searchWord); console.log('search group'); } } } - findUser(name: String) { - const headers = new Headers(); - headers.set('Content-Type', 'application/json'); - this.http.post(environment.graphQLUrl, this.searchService.buildJsonUser(name)) + findUser(name: string) { + this.searchService.search(name) .subscribe(response => { - this.foundUsers = this.searchService.renderUsers(response.json()); - this.foundGroups = this.searchService.renderGroups(response.json()); + this.foundUsers = this.searchService.getUsersForResponse(response); + this.foundGroups = this.searchService.getGroupsForResponse(response); for (const foundUser of this.foundUsers) { foundUser.allowedToSendRequest = this.requestService.isAllowedToSendRequest(foundUser.userID, this.user); } diff --git a/src/app/models/interfaces/IGroup.ts b/src/app/models/interfaces/IGroup.ts new file mode 100644 index 0000000..08c7240 --- /dev/null +++ b/src/app/models/interfaces/IGroup.ts @@ -0,0 +1,20 @@ +import {IUser} from './IUser'; + +export interface IGroup { + + id: number; + + name: string; + + creator: IUser; + + admins: IUser[]; + + members: IUser[]; + + chat: any; + + events: any; + + joined: boolean; +} diff --git a/src/app/models/interfaces/ISearchResult.ts b/src/app/models/interfaces/ISearchResult.ts new file mode 100644 index 0000000..320da14 --- /dev/null +++ b/src/app/models/interfaces/ISearchResult.ts @@ -0,0 +1,12 @@ +import {IUser} from './IUser'; +import {IGroup} from './IGroup'; + +export interface ISearchResult { + users: IUser[]; + + groups: IGroup[]; + + posts: any[]; + + events: any[]; +} diff --git a/src/app/models/interfaces/IUser.ts b/src/app/models/interfaces/IUser.ts new file mode 100644 index 0000000..a55aaaa --- /dev/null +++ b/src/app/models/interfaces/IUser.ts @@ -0,0 +1,36 @@ +import {IGroup} from './IGroup'; + +export interface IUser { + + id: number; + + name: string; + + handle: string; + + profilePicture?: string; + + level: number; + + points: number; + + numberOfPosts: number; + + postCount: number; + + posts: any[]; + + joinedAt: Date; + + friendCount: number; + + friends: IUser[]; + + groupCount: number; + + groups: IGroup[]; + + eventCount: number; + + events: any[]; +} diff --git a/src/app/services/base.service.ts b/src/app/services/base.service.ts new file mode 100644 index 0000000..ddae9e7 --- /dev/null +++ b/src/app/services/base.service.ts @@ -0,0 +1,16 @@ +import {Injectable} from '@angular/core'; +import {HttpHeaders} from '@angular/common/http'; + +@Injectable({ + providedIn: 'root' +}) +export abstract class BaseService { + protected headers: HttpHeaders; + + protected constructor() { + this.headers = new HttpHeaders(); + this.headers.set('Content-Type', 'application/json'); + } + + abstract buildRequestBody(...params: any): any; +} diff --git a/src/app/services/search/search.service.ts b/src/app/services/search/search.service.ts index 9269dcb..3b0a3fc 100644 --- a/src/app/services/search/search.service.ts +++ b/src/app/services/search/search.service.ts @@ -1,71 +1,109 @@ import {Injectable} from '@angular/core'; -import {Headers, Http} from '@angular/http'; +import {HttpClient} from '@angular/common/http'; import {DatasharingService} from '../datasharing.service'; import {Router} from '@angular/router'; -import {environment} from 'src/environments/environment'; -import { User } from 'src/app/models/user'; -import { GroupInfo } from 'src/app/models/groupinfo'; +import {User} from 'src/app/models/user'; +import {GroupInfo} from 'src/app/models/groupinfo'; +import {Observable} from 'rxjs'; +import {ISearchResult} from '../../models/interfaces/ISearchResult'; +import {environment} from '../../../environments/environment'; +import {BaseService} from '../base.service'; +import {tap} from 'rxjs/operators'; + +interface ISearchRequestResult { + data: { + search: ISearchResult; + }; +} + +const graphqlQuery = `query($query: String!, $first: Int, $offset: Int) { + search(query:$query, first: $first, offset: $offset) { + users{ + profilePicture, + name, + id, + handle, + points, + level, + friends { + id + } + } + groups{ + id + name + creator{id name handle} + members{id name handle} + } + } +}`; @Injectable({ providedIn: 'root' }) -export class SearchService { +export class SearchService extends BaseService { - users: Array; - constructor(private http: Http, private data: DatasharingService, private router: Router) { + users: User[]; + constructor(private http: HttpClient, private data: DatasharingService, private router: Router) { + super(); } - public renderUsers(pResponse: any): Array { + /** + * Maps the users in the response to the user class + * @param response + */ + public getUsersForResponse(response: ISearchRequestResult): User[] { const users = new Array(); - for (const user of pResponse.data.search.users) { - const pUser = new User(); - pUser.profilePicture = user.profilePicture; - pUser.username = user.name; - pUser.userID = user.id; - pUser.handle = user.handle; - pUser.points = user.points; - pUser.level = user.level; - pUser.friends = user.friends; - users.push(pUser); + for (const foundUser of response.data.search.users) { + const user = new User(); + user.profilePicture = foundUser.profilePicture; + user.username = foundUser.name; + user.userID = foundUser.id; + user.handle = foundUser.handle; + user.points = foundUser.points; + user.level = foundUser.level; + // @ts-ignore + user.friends = foundUser.friends; + users.push(user); } return users; } - public renderGroups(pResponse: any): Array { + /** + * Maps the groups in the response to the group class + * @param response + */ + public getGroupsForResponse(response: ISearchRequestResult): Array { const groups = new Array(); - for (const group of pResponse.data.search.groups) { + for (const group of response.data.search.groups) { groups.push(new GroupInfo(group.id, group.name)); } return groups; } - public buildJsonUser(name_: String): any { - const body = { - query: `query($name: String!) { - search(query:$name, first: 100, offset: 0) { - users{ - profilePicture, - name, - id, - handle, - points, - level, - friends { - id - } - } - groups{ - id - name - creator{id name handle} - members{id name handle} - } - } - }` - , variables: { - name: name_ + /** + * Searches for users, groups, events and posts with a specified query. + * @param query + */ + public search(query: string): Observable { + const body = this.buildRequestBody(query); + return this.http.post(environment.graphQLUrl, body, {headers: this.headers}) + } + + /** + * Builds the body for the request + * @param query - the search query + * @param first - the limit of elements to fetch + * @param offset - offset + */ + private buildRequestBody(query: String, first: number = 20, offset: number = 0): any { + return { + query: graphqlQuery, + variables: { + query, + first, + offset } }; - return body; } } diff --git a/tslint.json b/tslint.json index a3a101d..7761f3f 100644 --- a/tslint.json +++ b/tslint.json @@ -70,7 +70,7 @@ ], "no-misused-new": true, "no-non-null-assertion": true, - "no-redundant-jsdoc": true, + "no-redundant-jsdoc": false, "no-shadowed-variable": true, "no-string-literal": false, "no-string-throw": true,