import { Event } from '../classes/event.class' import { App } from '../gogocarto' declare let $: any, L: any export class Request { constructor( public route: string, public data: any, ) {} } export class AjaxModule { onNewElements = new Event() isRetrievingElements = false currElementIdRetrieving: number currBoundsRetrieving: L.LatLngBounds[] requestWaitingToBeExecuted = false waitingRequestFullRepresentation: boolean = null currRequest: Request = null loaderTimer = null allElementsReceived = false constructor() {} sendRequest(route: string, method: string, data: any, callbackSuccess?, callbackFailure?) { // console.log("SendAjaxRequest to " + route, data); $.ajax({ url: route, method: method, data: data, success: (response) => { if (response && callbackSuccess) callbackSuccess(response) }, error: (response) => { // when working with cross domain, there is a bug the server return empty response (status code = 0) // even if the request has been completed if (response.status == 0 && callbackSuccess) callbackSuccess(response) else if (callbackFailure) callbackFailure(response.data) }, }) } getElementById(elementId, callbackSuccess?, callbackFailure?) { if (elementId == this.currElementIdRetrieving) return this.currElementIdRetrieving = elementId $.ajax({ url: this.getSingleElementApiUrl(elementId), method: 'get', data: {}, success: (response) => { if (response) { let elementJson if (response.data) elementJson = Array.isArray(response.data) ? response.data[0] : response.data else elementJson = response if (callbackSuccess) callbackSuccess(elementJson) } else if (callbackFailure) callbackFailure(response) this.currElementIdRetrieving = null }, error: (response) => { if (callbackFailure) callbackFailure(response) this.currElementIdRetrieving = null }, }) } getElementsInBounds($bounds: L.LatLngBounds[], getFullRepresentation = false, expectedFilledBounds: L.LatLngBounds) { if (this.currBoundsRetrieving && $bounds[0] && $bounds[0].equals(this.currBoundsRetrieving[0])) return this.currBoundsRetrieving = $bounds // if invalid location we abort if (!$bounds || $bounds.length == 0 || !$bounds[0]) { return } const boundsResult = this.convertBoundsIntoParams($bounds) const bnds = boundsResult.boundsJson const dataRequest: any = { bounds: boundsResult.boundsString, boundsJson: JSON.stringify(boundsResult.boundsJson), categories: App.currMainId != 'all' ? [App.currMainId] : null, fullRepresentation: getFullRepresentation, ontology: getFullRepresentation ? 'gogofull' : 'gogocompact', stampsIds: App.request.stampsIds, } let route if (getFullRepresentation) route = App.config.data.elementsApiUrl else route = App.config.data.elementsCompactApiUrl || App.config.data.elementsApiUrl this.sendAjaxElementRequest(new Request(route, dataRequest), expectedFilledBounds) } private convertBoundsIntoParams($bounds: L.LatLngBounds[]) { let stringifiedBounds = '' const digits = 5 const boundsLessDigits = [] for (let bound of $bounds) { const southWest = L.latLng( L.Util.formatNum(bound.getSouthWest().lat, digits), L.Util.formatNum(bound.getSouthWest().lng, digits), ) const nortEast = L.latLng( L.Util.formatNum(bound.getNorthEast().lat, digits), L.Util.formatNum(bound.getNorthEast().lng, digits), ) bound = L.latLngBounds(southWest, nortEast) boundsLessDigits.push(bound) stringifiedBounds += bound.toBBoxString() + ';' } // some API endpoint needs a fixed number of bounds equals to 4 if ($bounds.length < 4) { const emptyBound = L.latLngBounds(L.latLng(0, 0), L.latLng(0, 0)) for (let i = $bounds.length; i < 4; i++) boundsLessDigits.push(emptyBound) } return { boundsString: stringifiedBounds, boundsJson: boundsLessDigits } } private getSingleElementApiUrl($elementId: any): string { let route = '' if (App.config.data.elementByIdUrl) { route = App.config.data.elementByIdUrl if (route.indexOf('{ID}') > 0) route = route.replace('{ID}', $elementId.toString()) else { if (route.slice(-1) != '/') route += '/' route += $elementId } } else route = App.config.data.elementsApiUrl + '/' + $elementId return route } private sendAjaxElementRequest($request: Request, $expectedFilledBounds = null) { if (this.allElementsReceived) { /*console.log("All elements already received");*/ return } // console.log("Ajax send elements request ", $request); if (this.isRetrievingElements) { //console.log("Ajax isRetrieving"); this.requestWaitingToBeExecuted = true this.waitingRequestFullRepresentation = $request.data.fullRepresentation return } this.isRetrievingElements = true this.currRequest = $request // let start = new Date().getTime(); $.ajax({ url: $request.route, method: 'get', data: $request.data, beforeSend: () => { this.loaderTimer = setTimeout(function () { $('#directory-loading').show() }, 1500) }, success: (response) => { if (typeof response == 'string') response = JSON.parse(response) if (response.data !== null) { // let end = new Date().getTime(); // console.log('Ajax receive ' + response.data.length + ' elements'); response.fullRepresentation = response.ontology == 'gogocompact' ? false : true if ($expectedFilledBounds) App.boundsModule.updateFilledBoundsWithBoundsReceived( $expectedFilledBounds, $request.data.categories, $request.data.fullRepresentation, ) if (response.allElementsSends || !App.config.data.requestByBounds) this.allElementsReceived = true this.onNewElements.emit(response) } }, complete: () => { this.isRetrievingElements = false this.currBoundsRetrieving = null clearTimeout(this.loaderTimer) setTimeout(() => $('#directory-loading').hide(), 250) if (this.requestWaitingToBeExecuted) { //console.log("REQUEST WAITING TO BE EXECUTED, fullRepresentation", this.waitingRequestFullRepresentation); App.elementsManager.checkForNewElementsToRetrieve(this.waitingRequestFullRepresentation) this.requestWaitingToBeExecuted = false } }, }) } }