angularangular-google-maps

How can I get a reference of the sender circle in angular google maps component


When I use circle events in Angular Google Maps component (https://github.com/angular/components/tree/main/src/google-maps), I cannot get a reference to the affected circle instance for retrieving the modified data.

E.g. I have multiple editable and draggable circles on the map.

<map-circle *ngFor="let c of ConCircles"
            [center]="c.center"
            [options]="c.options"
            [radius]="c.radius"
            (centerChanged)="CircleCenterChanged($event)"
            (radiusChanged)="CircleRadiusChanged($event)">
</map-circle>

The ConCircles element model looks like this:

this.ConCircles.push({
            center: {
                lat: startLat,
                lng: startLon,
            } as google.maps.LatLngLiteral,
            options: {
                fillColor: this.api.MapColors[this.ConCircles.length],
                strokeWeight: 1,
                fillOpacity: 0.8,
                editable: true,
                draggable: true,
                clickable: true,
            } as google.maps.CircleOptions,
            radius: (maxDist * 1000) as number
        });

I try to use the radiusChanged event to retrieve the new radius of the currently edited circle, and I try to use the centerChanged event to save the new center coordinate back into the model behind. But since these events have no arguments ($event is undefined), I cannot retrieve the changed values.

Package versions:

 "@angular/core": "16.1.1",
 "@angular/google-maps": "16.1.1"

Any help is appreciated.


Solution

  • Finally I found out that using @ViewChildren decorator helps.

    Template: Use a template reference variable, e.g. #circleRef.

    Then declare ngFor index (i) and pass it to the event handlers where we need an instance of the MapCircle object.

    <google-map ...>
        ...
        <map-circle #circleRef
                    *ngFor="let c of ConCircles; let i = index"
                    [center]="c.center"
        
                    [options]="c.options"
                    [radius]="c.radius"
                    (centerChanged)="CircleCenterChanged($event, c, i)"
                    (radiusChanged)="CircleRadiusChanged($event, c, i)">
        </map-circle>
        ...
    </google-map>
    
    

    Code behind: Declare a QueryList property with @ViewChildren decorator for holding all MapCircle instances created on the map.

    @ViewChildren(MapCircle) map_circles: QueryList<MapCircle>;
    

    Event handler functions: I'm not sure that this is the best way the do the validity check on a QueryList, but it looks reasonable.

    Check the map_circles list for dirtiness and if it has any items using the map_circles.dirty and map_circles.first properties.

    If it is not dirty and it has items, then try to get the idxth item of the collection by first converting it to an array, then index into it.

    Then do null-guard.

        CircleRadiusChanged(args: any, c: ConCircle, idx: number) {
            if (this.map_circles.dirty || this.map_circles.first === undefined) {
                return;
            }
            const modifiedCircle = this.map_circles.toArray()[idx];
    
            if (!modifiedCircle) {
                return;
            }
            // ...
        }