All files / modules adhoc.ts

62.68% Statements 42/67
64.7% Branches 22/34
70% Functions 7/10
59.67% Lines 37/62

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 1814x   4x   4x   4x 4x 4x 4x 4x                 4x                 8x                                         8x     26x     8x 8x     8x 8x     8x 8x 8x     8x       8x 2x 2x       8x 8x 1x     7x     8x 8x   4x 4x             4x   4x 3x 2x 2x     1x                                                                                                                                                      
import { Injectable } from '@angular/core';
 
import { take } from 'rxjs/operators';
 
import { AppConstants } from '@unpispas/upp-defs';
import { HttpResponseTypes, HttpSerializer } from './http';
import { stateService } from './state';
import { toastService } from './toasts';
import { downloadService } from './upload';
import { languageService } from './language';
import { httpService } from './http';
 
/**
 * @class adhocService
 * @description Service for handling HTTP requests with additional custom parameters, error handling, and toast notifications.
 */
@Injectable({
    providedIn: 'root'
})
export class adhocService {
 
    /**
     * @constructor
     * @param {languageService} lang - Service for managing application language settings.
     * @param {stateService} state - Service for managing session and device state information.
     * @param {httpService} http - Service for handling HTTP requests.
     * @param {toastService} toast - Service for displaying toast notifications.
     */    
    constructor(private lang: languageService, private state: stateService, private http: httpService, private toast: toastService, private download: downloadService){
        // nothing to do
    }
 
    /**
     * @method DoRequest
     * @description Sends an HTTP GET or POST request based on the provided parameters. 
     * It includes additional custom query parameters (device, session, and language), handles errors, and shows toast notifications if needed.
     * 
     * @param {string} url - The URL endpoint for the request.
     * @param {any} [params=null] - Optional query parameters to append to the request URL.
     * @param {any} [post=null] - Optional body for a POST request. If null, a GET request is made.
     * @param {boolean} [showtoast=true] - Whether to show a toast notification on error.
     * @param {any} [headers=null] - Optional HTTP headers to include in the request.
     * @param {HttpResponseTypes | null} [responseType=null] - Optional response type for the request.
     * @param {HttpSerializer | null} [serializer=null] - Optional serializer for the request.
     * @param {number | null} [timeout=null] - Optional timeout duration for the request.
     * 
     * @returns {Promise<any>} A promise that resolves with the response data if successful, or rejects with an error message.
     */    
    DoRequest(url: string, params: any = null, post: any = null, showtoast = true, headers: any = null, responseType: HttpResponseTypes | null = null, serializer: HttpSerializer | null = null, timeout: number | null = null) : Promise <any>{
        let _getparams = ''
 
        function _sep(_getparams:string){
            return (_getparams.length == 0) ? '?' : '&';
        }
 
        if (this.state.device){
            _getparams += _sep(_getparams) + "device=" + this.state.device;            
        }
 
        if (this.state.session){
            _getparams += _sep(_getparams) + "session=" + this.state.session;
        }
        
        const _lang = this.lang.GetLanguage(true);
        if (_lang){
            _getparams += _sep(_getparams) + "lang=" + _lang;
        }
 
        Iif (this.state.place){
            _getparams += _sep(_getparams) + "place=" + this.state.place;
        }
 
        if (params){
            for(const _param in params){
                _getparams += _sep(_getparams) + _param + "=" + params[_param];
            }    
        }
        
        let _request = null;
        if (post){
            _request = this.http.post(AppConstants.baseURL + url + _getparams, post, (headers) ? headers : httpService.headers, responseType, serializer, timeout);
        }
        else {
            _request = this.http.get(AppConstants.baseURL + url + _getparams, true, (headers) ? headers : httpService.headers, responseType, timeout);
        }
 
        return new Promise((resolve, reject) => {
            _request.pipe(take(1)).subscribe({
                next: (data) => {
                    if (data !== null){
                        resolve(data);
                    }
                    else E{
                        reject("no response");
                    }
                },
                error: (error) => {
                    reject(error);
 
                    if (showtoast){
                        if (error.status != 0){
                            this.toast.ShowAlert('danger', this.lang.tr('@http_request_error', [ error.status ]));
                            console.error(this.lang.tr('@http_request_error', [ error.status ]));                        
                        }
                        else {
                            console.error("[HTTP] status = 0 (you are offline)");
                        }
                    }    
                },
                complete: () => {
                    // nothing to do
                }
            });
        });
    }
 
    /**
     * @method Download
     * @description Downloads a file from a given URL, either saving it locally or opening it in a new tab.
     * It also manages UI interactions like showing a loading indicator while the file is being fetched.
     * 
     * @param {string} url - The URL from which the file should be downloaded.
     * @param {string} filename - The desired filename for the downloaded file.
     * @param {any} [headers=null] - Optional HTTP headers to include in the request, used for determining file type.
     * @param {boolean} [download=true] - If `true`, the file will be downloaded. If `false`, it will be opened in a new tab.
     * @param {string | null} [target=null] - If `download` is `false`, this sets the target attribute for opening the file (e.g., `_blank`).
     * 
     * @returns {Promise<boolean>} A promise that resolves to `true` if the file is successfully downloaded or opened, or `false` if the download fails.
     * 
     * @example
     * // Download a file and save it locally
     * await adhocService.Download('https://example.com/file.pdf', 'myfile.pdf');
     * 
     * @example
     * // Open a file in a new tab instead of downloading
     * await adhocService.Download('https://example.com/file.pdf', '', null, false, '_blank');
     */    
    async Download(url: string, filename: string, headers: any = null, download=true, target=null): Promise <boolean> {
        let data = null;
 
        console.info("[DOWNLOAD] url: '" + url + "'");
 
        this.toast.ShowWait();
        try {
            data = await this.download.file(url);
        }
        catch {
            // nothing to do
        }
        this.toast.HideWait();
 
        Iif (data){
            const file = new Blob([data], { type: headers ? headers['Content-Type'] : 'application/octet-stream' });
 
            const link = document.createElement("a");
            link.href = URL.createObjectURL(file);
            console.info("[DOWNLOAD] href: '" + link.href + "'");
 
            if (!download){     // open file in new page (if target = '_blank')
                Iif (target) {
                    link.target = target;
                }
            }
            else {          // download the file
                link.download = filename;
            }
 
            document.body.appendChild(link);
            link.click();
 
            setTimeout(() => {
                document.body.removeChild(link);
                URL.revokeObjectURL(link.href)
            }, 60000);  // wait 1 minute
 
            return true;
        }
 
        return false;   // no data has been donloaded
    }
}