Home > Enterprise >  Angular - agm seems to be blocking rendering
Angular - agm seems to be blocking rendering

Time:02-17

I have an Angular app (13.0.2), with Angular Google Maps. I am also using agm markers.

In the template, I have a dropdown that filters the map points by type. While the filtering is in progress, I want to put a loading div, and hide the map. This is controlled by an isLoading boolean.

The problem is that whatever I do, it waits for the filter to happen, and only then renders the loading div. I logged the isLoading value, and it evaluates to true when it should, however it seems that Angular is waiting for the map points to finish filtering before rendering...

This is the dropdown in the template:

<div >
   <div >
        <label for="agm-tecnhology" >{{technologyLabel}}</label>
   </div>
   <div >
        <select  id="agm-tecnhology" [value]="selectedInstallationType" (change)="onFilterByTechnology($event.target.value)" [disabled]="isLoading">
            <option value="all">{{showAllLabel}}</option>
            <option *ngFor="let technology of technologies" [value]="technology">{{ technology }}</option>
        </select>
    </div>
</div>

this is onFilterByTechnology, and the filtering method that it calls:

onFilterByTechnology(technology) {    
    this.isLoading = true;
    
    this.selectedTechnology = technology;

    this.filterByTechnology();   
}

filterByTechnology() {
    this.infoWindowOpened = null;  

    this.waypoints = this.waypointsInitial.filter((marker) => {
        return this.selectedTechnology === 'all' && this.selectedCountry === 'all' ?
                marker : 
                this.selectedTechnology === 'all' && this.selectedCountry !== 'all' ?
                marker.Country === this.selectedCountry :
                this.selectedTechnology !== 'all' && this.selectedCountry === 'all' ?
                marker.Technology === this.selectedTechnology :
                marker.Technology === this.selectedTechnology && marker.Country === this.selectedCountry;          
    });

    this.isLoading = false;
} 

and this is the map in the template:

<agm-map  [ngClass]="isLoading ? 'hide' : ''" [fitBounds]="bounds" [zoom]="defaultZoom" [minZoom]="2" [maxZoom]="18" [latitude]="latitude" [longitude]="longitude">
<appDirectionsMap [mapData]="mapData" (routeChanged)="routeChangedHandler($event)"></appDirectionsMap>
<ng-container *ngIf="hasRadius">
    <agm-circle *ngFor="let marker of waypoints" [latitude]="marker.Latitude" [longitude]="marker.Longitude" [radius]="circleRadiusInKm" [fillColor]="'#2777B8'" [fillOpacity]="0.4" [strokePosition]="0" [strokeColor]="'00205B'" [strokeOpacity]="0.4" [strokeWeight]="0.5" (circleClick)="circleWasClicked($event, circleInfoWindow)">
        <agm-info-window [latitude]="clickLat" [longitude]="clickLng" #circleInfoWindow>
            <ng-container [ngTemplateOutlet]="markerDetails" [ngTemplateOutletContext]="{marker:marker}"></ng-container>
        </agm-info-window>
    </agm-circle>
</ng-container>

<ng-container *ngIf="!hasRadius">
    <agm-marker-cluster [averageCenter]="true" [maxZoom]="17" [styles]="[{url: 'Frontend/assets/images/cluster.png', textColor: '#fff', textSize: '14', height: '36', width: '36'}]">
        <agm-marker *ngFor="let marker of waypoints" [style.backgroundColor]="red" [iconUrl]="'Frontend/assets/images/markerdarkblue.png'" [latitude]="marker?.Latitude" [longitude]="marker?.Longitude" (markerClick)="markerWasClicked(markerInfoWindow)">
            <agm-info-window [latitude]="clickLat" [longitude]="clickLng" #markerInfoWindow>
                <ng-container [ngTemplateOutlet]="markerDetails" [ngTemplateOutletContext]="{marker:marker}"></ng-container>
            </agm-info-window>
        </agm-marker>    
    </agm-marker-cluster>            
</ng-container> 

So I filter on technology, the isLoading is true, but the map doesn't get the hide class until after the filtering. When the filter is finished, the hide class is added, and I get the loading div, etc.

It is as if somehow the map is blocking the updating until filtering is finished. I tried forcing detectChanges(), to no avail.

Does anyone have an idea what I might be doing wrong?

Thanks a lot :)

CodePudding user response:

Maybe not an answer, but a workaround -

I added a timeout on filterByTechnology(), and now it works as it should.

setTimeout(() => this.filterAdBluePlantsByTechnology(), 0);

CodePudding user response:

Here is an approach that works - conditionally set the hidden attribute on <agm-map>:

[attr.hidden]="loading ? true : null"

Stackblitz (click the map to simulate a 2 second load): https://stackblitz.com/edit/angular-google-maps-agm-map-mqso1g?file=app/app.component.html

  • Related