1

i am trying to make and bing component in angular 4 and it wont let me render the map at all..

This is my index.html file:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Microsoft</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?branch=experime‌​ntal'></script>
</head>
<body onload="AppComponent.helloWorld()">
<div id="myMap"></div>
  <app-root></app-root>
</body>
</html>

this is my component:

 export class AppComponent implements OnInit {
  @ViewChild('myMap') myMap;
  title = 'app';

  ngOnInit() {
    if(Microsoft !== undefined){
    var map = new Microsoft.Maps.Map(this.myMap.nativeElement, {
      credentials: 'key goes here'
    });
  }}
}

component HTML File:

<div #myMap style='width: 100%; height: 500px;'></div>

I don't know what i am doing wrong. but i can't get the map to load. it's throwing can not read property 'prototype' of null error.

Michael B
  • 1,660
  • 3
  • 28
  • 59
vineeth
  • 114
  • 1
  • 14

3 Answers3

0

At the time ngOnInit() is executed, #myMap doesn't exists, so move the code to ngAfterViewChecked().

Vega
  • 27,856
  • 27
  • 95
  • 103
0

Elements queried with the @ViewChild decorator aren't available until the ngAfterViewInit() lifecycle check is ran. They will be undefined in ngOnInit(). Try moving that declaration to

ngAfterViewInit() {
  if(Microsoft !== undefined){
    var map = new Microsoft.Maps.Map(this.myMap.nativeElement, {
    credentials: 'key goes here'
    });
 }
}

Although I don't see in your code where the 'Microsoft' object is being defined. Are you importing that separately and you just didn't include it?

diopside
  • 2,981
  • 11
  • 23
  • I did not include anything. Can you please tell me what i need to import? What do you mean by microsoft Object. – vineeth Aug 23 '17 at 14:43
  • Well, I'm not really sure what it is, I just know that 'Microsoft' is not a native object in typescript or angular... so it needs to be defined somewhere...In this line - if(Microsoft !== undefined) Its referring to a Microsoft object but its not clear where that object gets defined, if ever. I would assume its imported by that bing script tag, but you'd have to look at the source. Where did you get the code that you are currently using in the component? – diopside Aug 23 '17 at 14:46
  • I just used the script tag like you said and looked at the MSDN and there they used the new Microsoft.Maps.Maap( .... ) to initialize the map. I am doing the same thing. I did this with google maps and it worked perfectly fine. Now our company is asking to look into bing maps coz they have contracts with microsoft. soo ... anyways. i just declared the Microsoft at the top of the component like.. declare var MIcrosoft; – vineeth Aug 23 '17 at 14:50
  • Im still getting the same error. Im new to angular as you can tell. – vineeth Aug 23 '17 at 14:53
  • I just realized you included content from your 'index.html' file instead of your app.component.html' file. Your angular app won't be aware of many things that happen inside that index.html file after the app is bootstrapped, and I'm assuming it loads before that bing script is fully loaded. So it wont ever have any clue what that Microsoft namespace is regardless of when you check for it. You'd probably need to include the bing script in your package json file, and maybe define a new namespace for 'Microsoft' , otherwise typescript wont know what to do with it. – diopside Aug 23 '17 at 14:53
  • https://stackoverflow.com/questions/38855891/angular-cli-webpack-how-to-add-or-bundle-external-js-files – diopside Aug 23 '17 at 14:54
  • I tried that and it failed to load. one thing i wanna mention is that if i delete the script tag tah in index.html file, it says Microsoft not defined. But when i put it back again it says, can not read property 'prototype' of null. – vineeth Aug 23 '17 at 15:05
  • Because its seeing a capitalized variable identifier that it doesn't understand, but which it knows should refer to an Object, so its trying to read its 'prototype' property to see what type of object it is, and bc it hasn't been imported fully or propertly, its returning an error . It doesn't yet have a prototype. – diopside Aug 23 '17 at 15:08
  • I just changed the link from v8 to v7 and it worked. :| I dont know if there is a way to follow you but if there is i would. You seem very knowledgeable and i can learn a lot from you. thank you for everything man. I really appreciate it. – vineeth Aug 23 '17 at 15:22
0

I finally figured it out. well, its actually my colleague.

So the idea is to wait till the document is ready and then load the component.

So in the app component: disclaimer: Do not copy this code, It will not work. I am just free handing here.

@Component({
    selector: 'app-root',
    template: '<bing-maps *ngIf="ready"></bing-maps'

})
export class app implements onInit {
ready: boolean;

constructor() {}
ngOnInit(){

document.onreadystatechange = () => {
     if(document.readyState === "complete"){
        this.ready = true
     }
   }

}

}

thats the idea, in the bing-maps component you you have the div with the id="myMap" and in its onInit() you give the credentials.

vineeth
  • 114
  • 1
  • 14