File

src/lib/service/autocomplete/autocomplete.service.ts

Index

Properties
Methods

Constructor

constructor(backendService: BackendService, userService: UserService, eventService: EventService)
Parameters :
Name Type Optional
backendService BackendService no
userService UserService no
eventService EventService no

Methods

getAutocompleteUrlData
getAutocompleteUrlData(url: string)

Fetches autocomplete data by processing the URL with the provided parameters and making an HTTP GET request.

Parameters :
Name Type Optional Description
url string no
  • The URL template to be processed.
  • An observable containing the autocomplete response.
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 :
Name Type Optional Description
url string no
  • The original URL with placeholders.
params SearchParams no
  • An object containing additional parameters to be used in the URL.
formElements literal type no
  • An object containing form element changes.
Returns : string
  • The processed URL with all placeholders replaced and parameters updated.

Properties

FIELD_PREFIX
FIELD_PREFIX: string
Type : string
Default value : '{field:'
formElements
formElements: literal type
Type : literal type
Default value : {}
STATIC_PLACEHOLDERS
STATIC_PLACEHOLDERS: []
Type : []
Default value : ['schemalocale', 'clientlocale']
staticPlaceholderValues
staticPlaceholderValues: object
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()
    };
  }
}

results matching ""

    No results matching ""