4

I am just grasping Angular (6) framework, and it's quirks and features. And there is this one thing, that I would need, but as it seems, it goes against Angular paradigms - a service, that needs a reference to DOM node.

More specifically - Esri Map component. In it's constructor, it requires a DOM node - a place where the map will live. Since the Map is going to be the center thing in the application, it would be used by multiple components throughout the app. And for that, I would want it in a service. Question is - how would I do that? I made solution to this, but I would like to validate it with more experienced Angular devs.

So I have a MapComponent that would be like a singleton component - included only once in the App.

export class MapComponent implements OnInit {
  @ViewChild('map') mapElement:ElementRef;
  constructor(
    private renderer2: Renderer2,
    private mapService: MapService) { }
  ngOnInit() {
    // This is where I pass my DOM element to the service, to initialize it
    this.mapService.init(this.mapElement.nativeElement);
  }
}

And my mapService, that I would reference throughout other services

@Injectable()
export class MapService {
    private isInit:boolean = false;
    private map: __esri.Map = null;
    private mapView: __esri.MapView = null;
    init(domElement: ElementRef) {
        if (this.isInit) return Promise.resolve(); // A guard? 
        loadModules(["esri/Map", "esri/views/MapView", "esri/widgets/ScaleBar"])
            .then(([Map, MapView, ScaleBar]) => {
                this.map = new Map();
                this.mapView = new MapView({
                    map: this.map,
                    container: domElement // This is where I need DOM element
                });
            })
            .catch(err => {
                // handle any errors
                console.error(err);
            })
            .then(() => {
                this.isInit = true;
            });
    }
}

This does work, I just wonder, would this be a correct way to do it. I require these map objects to be accessible through other components, to add/remove/change map layers, draw/render geometries and other map things.

Wish
  • 1,594
  • 1
  • 18
  • 36
  • I think it seems like an appropriate approach if the app is with reasonable size , but i if this app planed to grow a lot , I might try to separate all of the map visualization logic in a single component and pass the events changing the map trough a ngrx store, in order for the code logic to be more manageable and understandable , because lets say for example in the end you have 100 ways to modify the map and you store all that logic in that single service, it wont be nice. – Християн Христов Jun 01 '18 at 21:25

0 Answers0