0
votes

I have an app with multiple pages (anguler-router, roter-outlet set up to show angular components...). On one of the pages I have an external lib, that I built myself, and have published to a company hosted NPM repo. My lib works fine when I type the URL in manually, but when I route with routerLink, the parent component (afgm-map) gets an empty array for @ContentChildren (afgm-marker). In the afgm-map component I have put in a console.log(markerRefs), which prints the marker/s when I go to the page, but when I route to the page with a link it prints an empty array.

:(

If I have used link to get to the page and press F5, it work fine. Any ideas?

On my pageTemplate I render the lib like so:

<afgm-map [center]="data.position" (toggleExpand)="expandMap($event)">
  <afgm-marker [position]="data.position"></afgm-marker>
</afgm-map>

The map component ts code with a console log for debugging:

export class MapComponent implements OnInit {
  @Input()
  center!: google.maps.LatLng;
  @Input()
  zoom = 15;
  @Output()
  toggleExpand: EventEmitter<boolean> = new EventEmitter();
  @ViewChild('mapViewPort')
  mapViewPort: ElementRef;

  @ContentChildren(MarkerComponent)
  markersRefs: MarkerComponent[] = [];

  expanded: boolean;
  map: any;
  markers: google.maps.Marker[];

  constructor() {}

  ngOnInit() {
    ...
      this.onInit();
  }

  onInit() {
    this.map = new google.maps.Map(this.mapViewPort.nativeElement, {
      center: this.center,
      zoom: +this.zoom,
      disableDefaultUI: true,
      scaleControl: true
  });

console.log(this.markersRefs);

    this.markers = this.markersRefs.map(m => {
      return new google.maps.Marker({
        position: m.position,
        icon: m.icon,
        map: this.map
      });
    });
  }
  ...
}

The marker component is just a shell-component with no real logic/template:

export class MarkerComponent implements OnInit {
  @Input()
  position!: google.maps.LatLng;

  @Input()
  icon = '/assets/img/mapMarker49px.png';

  constructor() {}
}
1

1 Answers

0
votes

Seems to be a race condition. My map component is dependent on external script to be loaded, but I still expect angular to mount component in a deterministic way. What I did to fix it was to let the markers to ad them selves to the parent (DI parent in the constructor of the child, and the child then runs "mapComp.addMarker(this)") when the parent is done with it's setup it checks markers.length > 0 and runs renderMarkers(this.markers) and sets this.initialized = true. In the addMarker I check this.initialized === true if so I run renderMarkers([marker]). So it's both "belt" and "braces"...