BingMap - getting prototype of null error

不问归期 提交于 2019-12-01 12:49:33

In the map script URL you are using a different callback function that you o function to load the map. (loadScenario vs GetMap). Also, it looks like you are using the redirect URL rather than the documented map script URL (this will likely break in the future). Try changing the map script URL to this:

<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?branch=experimental&callback=GetMap' async defer></script>

Not sure what bing.js is in your app. Assuming this is where you have you map load code. You will want to load this before the map script otherwise the map script may load before your code does and thus try to load the map before your GetMap function is loaded into the page.

Alternatively, you may find this code sample useful: https://github.com/Microsoft/BingMapsV8CodeSamples/blob/master/Samples/Experimental/Map_WithAngular1.html

It seems you are generating a static map only in your view, in that case the loading of Bing Maps API (http://www.bing.com/api/maps/mapcontrol) and initializing map control (GetMap function) could be omitted.

The reason why you are getting the error:

TypeError: Cannot read property 'prototype' of null

is most likely due to missing map container declaration in your view

<div id="myMapL"></div>

Example

var app = angular.module("myApp", []);
app.controller("bingMapsCtrl", function ($scope) {
 
    $scope.Key = "As1l7HRtrpkXzjXozp3M2ufUTDvj16b2MHlpscQmHJEtxYFZWqwyccSx7I5XXEW_";

});
 <script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<div ng-app="myApp" ng-controller="bingMapsCtrl" ng-cloak>
        <!--div id="myMapL"></div-->
        <img
      ng-src='http://dev.virtualearth.net/REST/V1/Imagery/Map/Road/Bellevue%20Washington?mapLayer=TrafficFlow&amp;key={{Key}}'></img>
    </div>
Andreas

Seems BING MAP API 8 has some issues with reference order, will try to report to Rick.

Does not Work:

<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>

This fails on:

mapcontrol:11 Uncaught TypeError: Cannot read property 'prototype' of null
    at k (mapcontrol:11)
    at n.h [as create] (mapcontrol:11)
    at e (mapcontrol:11)
    at t.l [as instance] (mapcontrol:11)
    at n.h [as create] (mapcontrol:11)
    at e (mapcontrol:11)
    at t.l [as instance] (mapcontrol:11)
    at new Microsoft.Maps.Map (mapcontrol:13)
    at ChildScope.$scope.init (maptest.html:92)
    at HTMLDocument.<anonymous> (maptest.html:99)

Does Work:

<script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>

But... that breaks epoch and is not how Angular is to be loaded. So back to the drawingboard.

Issue solved for me after wrapping the "loadMap" method with a "setTimeout":

HTML

<div class="bing-map-container">
  <div id='printoutPanel'></div>
  <div #bingMap id="myMap" style='width: 100vw; height: 100vh;'></div>
</div>

Component

import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {BingMapService} from './bing-map.service';
import {Subscription} from "rxjs";

@Component({
  moduleId: module.id,
  selector: 'bing-map',
  styleUrls: ['./bing-map.component.css'],
  templateUrl: './bing-map.component.html'
})
export class BingMapComponent implements OnInit, OnDestroy {
  @ViewChild('bingMap') bingMap: any;
  serviceSubject: Subscription;

  constructor(
    private bingMapService: BingMapService
  ) {}

  loadMap() {
    const map = new Microsoft.Maps.Map(this.bingMap.nativeElement, {});
  }

  ngOnInit() {
    this.serviceSubject = this.bingMapService.injectionSubject().subscribe((loaded) => {
      if (loaded) {
        window.setTimeout(() => {
          this.loadMap();
        });
      }
    });

    this.bingMapService.injectBingMapMainScript();
  }

  ngOnDestroy() {
    if (this.serviceSubject) {
      this.serviceSubject.unsubscribe();
    }
  }
}

Service

import {Observable, Subject} from 'rxjs';
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';

@Injectable({
  providedIn: 'root'
})
export class BingMapService {
  private subject = new Subject<any>();

  constructor(
    private http: Http,
  ) {}

  injectBingMapMainScript() {
    let script = document.createElement('script');
    script.src = 'https://www.bing.com/api/maps/mapcontrol?key=[YourKey]';
    script.async = true;

    document.body.appendChild(script);

    script.onload = () => {
      this.subject.next(true);
    };
  }

  injectionSubject(): Observable<any> {
    return this.subject.asObservable();
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!