src/lib/service/autocomplete/autocomplete.service.ts
Properties |
Methods |
constructor(backendService: BackendService, userService: UserService, eventService: EventService)
|
||||||||||||
Parameters :
|
getAutocompleteUrlData | ||||||||
getAutocompleteUrlData(url: string)
|
||||||||
Fetches autocomplete data by processing the URL with the provided parameters and making an HTTP GET request.
Parameters :
Returns :
Observable<AutocompleteResponse>
|
getProcessedUrl | ||||||||||||||||
getProcessedUrl(url: string, params: SearchParams, formElements: literal type)
|
||||||||||||||||
Processes the URL by replacing placeholders with corresponding values from formElements or params, and removes or appends query parameters as necessary.
Parameters :
Returns :
string
|
FIELD_PREFIX |
FIELD_PREFIX:
|
Type : string
|
Default value : '{field:'
|
formElements |
formElements:
|
Type : literal type
|
Default value : {}
|
STATIC_PLACEHOLDERS |
STATIC_PLACEHOLDERS:
|
Type : []
|
Default value : ['schemalocale', 'clientlocale']
|
staticPlaceholderValues |
staticPlaceholderValues:
|
Type : object
|
Default value : {}
|
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs';
import {BackendService} from '../backend/backend.service';
import {AutocompleteResponse, SearchParams} from './autocomplete.interface';
import {UserService} from '../user/user.service';
import {EventService} from '../events/event.service';
import {EnaioEvent} from '../events/events';
const BASE_API_URL = '/app/';
@Injectable({
providedIn: 'root'
})
export class AutocompleteService {
FIELD_PREFIX = '{field:';
STATIC_PLACEHOLDERS = ['schemalocale', 'clientlocale'];
staticPlaceholderValues = {};
formElements: {[key: string]: string} = {};
constructor(private backendService: BackendService, private userService: UserService, private eventService: EventService,
) {
this.getStaticPlaceholders();
this.eventService.on(EnaioEvent.CLIENT_LOCALE_CHANGED).subscribe(() => {
this.getStaticPlaceholders();
});
this.eventService.on(EnaioEvent.SCHEMA_LOCALE_CHANGED).subscribe(() => {
this.getStaticPlaceholders();
});
}
/**
* Fetches autocomplete data by processing the URL with the provided parameters
* and making an HTTP GET request.
*
* @param {string} url - The URL template to be processed.
* @returns {Observable<AutocompleteResponse>} - An observable containing the autocomplete response.
*/
getAutocompleteUrlData(url: string): Observable<AutocompleteResponse> {
return this.backendService.get('api' + url, BASE_API_URL);
}
/**
* Processes the URL by replacing placeholders with corresponding values from formElements or params,
* and removes or appends query parameters as necessary.
*
* @param {string} url - The original URL with placeholders.
* @param {SearchParams} params - An object containing additional parameters to be used in the URL.
* @param {Object.<string, string>} formElements - An object containing form element changes.
* @returns {string} - The processed URL with all placeholders replaced and parameters updated.
*/
getProcessedUrl(url: string, params: SearchParams, formElements: {[key: string]: string}): string {
this.formElements = formElements;
const urlObj = new URL(url, window.location.origin);
const unusedKeys: string[] = [];
const updatedParams: {key: string; newValue: string | string[]}[] = [];
urlObj.searchParams.forEach((value, key) => {
if (this.isPlaceholder(value)) {
if (this.isFieldPlaceholder(value)) {
const fieldName = this.extractFieldName(value);
if (fieldName && this.formElements.hasOwnProperty(fieldName)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const fieldValue = (this.formElements[fieldName] as any)?.value || this.formElements[fieldName];
updatedParams.push({key, newValue: fieldValue});
} else {
unusedKeys.push(key);
}
} else if (this.hasStaticPlaceholder(value)) {
const replacedValue = this.replaceStaticPlaceholders(value);
updatedParams.push({key, newValue: replacedValue});
} else {
unusedKeys.push(key);
}
}
});
updatedParams.forEach(({key, newValue}) => {
this.replaceUrlParam(urlObj, key, newValue);
});
unusedKeys.forEach(key => {
urlObj.searchParams.delete(key);
});
Object.keys(params).forEach(key => {
if (urlObj.searchParams.has(key)) {
urlObj.searchParams.delete(key);
}
urlObj.searchParams.append(key, params[key]);
});
return urlObj.pathname + urlObj.search;
}
/**
* Checks if the provided value is a placeholder enclosed in curly braces '{}'.
*
* @param {string} value - The value to be checked.
* @returns {boolean} - True if the value is a placeholder, false otherwise.
*/
private isPlaceholder(value: string): boolean {
return (value.startsWith('{') || value.includes('{')) && value.endsWith('}');
}
/**
* Checks if the placeholder value starts with 'field:' indicating it references a form field.
*
* @param {string} value - The placeholder value to be checked.
* @returns {boolean} - True if the value starts with 'field:', false otherwise.
*/
private isFieldPlaceholder(value: string): boolean {
return value.startsWith(this.FIELD_PREFIX);
}
/**
* Extracts the field name from a placeholder that starts with 'field:'.
*
* @param {string} value - The placeholder value from which to extract the field name.
* @returns {string | null} - The extracted field name or null if extraction is not possible.
*/
private extractFieldName(value: string): string | null {
return value.substring(this.FIELD_PREFIX.length, value.length - 1);
}
/**
* Replaces a search parameter in the URL object with a new value.
*
* @param {URL} urlObj - The URL object where the search parameter should be replaced.
* @param {string} key - The search parameter key to be replaced.
* @param {string | string[]} newValue - The new value to set for the search parameter. Can be a string or an array of strings.
*/
private replaceUrlParam(urlObj: URL, key: string, newValue: string | string[]): void {
// Remove the existing placeholder key
urlObj.searchParams.delete(key);
// If newValue is an array, add each item as a separate parameter with the same key
if (Array.isArray(newValue)) {
newValue.forEach(value => {
urlObj.searchParams.append(key, value);
});
} else {
if (newValue) {
urlObj.searchParams.set(key, newValue);
}
}
}
/**
* Handles the replacement of a URL parameter by checking if the key exists in the provided
* params object. If not, it adds the key to the unusedKeys array.
*
* @param {URL} urlObj - The URL object where the parameter replacement should be handled.
* @param {Object.<string, string>} params - An object containing additional parameters to be used.
* @param {string} key - The search parameter key to be handled.
* @param {string[]} unusedKeys - An array to collect keys that are not used.
*/
private handleParamReplacement(urlObj: URL, params: {[key: string]: string}, key: string, unusedKeys: string[]): void {
if (params.hasOwnProperty(key)) {
this.replaceUrlParam(urlObj, key, params[key]);
} else {
unusedKeys.push(key);
}
}
/**
* Checks if the provided value has a static placeholder like {clientlocale} or {schemalocale}.
*
* @param {string} value - The value to check.
* @returns {boolean} - True if the value contains any static placeholders, false otherwise.
*/
private hasStaticPlaceholder(value: string): boolean {
return this.STATIC_PLACEHOLDERS.some(placeholder => value.includes(`{${placeholder}}`));
}
/**
* Replaces static placeholders in a given string with corresponding values from formElements.
*
* @param {string} value - The value containing static placeholders to be replaced.
* @returns {string} - The string with static placeholders replaced.
*/
private replaceStaticPlaceholders(value: string): string {
let updatedValue = value;
this.STATIC_PLACEHOLDERS.forEach(placeholder => {
if (updatedValue.includes(`{${placeholder}}`)) {
updatedValue = updatedValue.replace(`{${placeholder}}`, this.staticPlaceholderValues[placeholder] || '');
}
});
return updatedValue;
}
/**
* Fetches the static placeholders from the user service and stores them in the staticPlaceholderValues object.
*/
private getStaticPlaceholders(): void {
this.staticPlaceholderValues = {
[this.STATIC_PLACEHOLDERS[0]]: this.userService.getCurrentUser().getSchemaLocale(),
[this.STATIC_PLACEHOLDERS[1]]: this.userService.getCurrentUser().getClientLocale()
};
}
}