Ionic Google Map

I have been trying to add google map to my app using @ionic-native/google-map package but my map is visible only on 4.x Android versions not any other versions. Here is my piece of code.

export class MapPage{

map:GoogleMap;
mapElement:HTMLElement;
lati:any;
longi:any;
constructor(private googleMaps:GoogleMaps,private geolocation:Geolocation){}


ionViewDidLoad(){

    this.loadMap();
}

loadMap(){
this.geolocation.getCurrentPosition().then((pos) => {
this.lati=pos.coords.latitude;
this.longi=pos.coords.longitude;

this.mapElement=document.getElementById('map');


let mapOptions:GoogleMapOptions={
    camera:{
        target:{
          lat:this.lati,
          lng:this.longi
        },
        zoom:18,
        tilt:30
    }
};
console.log(mapOptions);
this.map=this.googleMaps.create(this.mapElement,mapOptions);
this.map.one(GoogleMapsEvent.MAP_READY)
.then(()=>{
    console.log("Map is Ready!");

    this.map.addMarker({
        title:'Ionic',
        icon:'blue',
        animation:'DROP',
        position:{
            lat:this.lati,
            lng:this.longi
        }
    })
    .then(marker =>{
        marker.on(GoogleMapsEvent.MARKER_CLICK)
        .subscribe(()=>{
            alert("clicked");
        });
    });
});

}).catch((error)=>{
console.log(ā€˜error get locationā€™,error);
});
}
}

Have you considered using ElementRef and ViewChild instead of document.getElementById to refer to the map? I think itā€™s always a helpful practice to stick to the frameworkā€™s features to enhance the performance of your appā€¦ In theory, you shouldnā€™t even need document functions in an Ionic app

1 Like

Thanks for help. It was some supporting libraries which were not installed after installing at SDK Manager in Android Studio and it worked!

@Sidharth_1999 is absolutely right. ViewChild should be the only way to access the DOM. Using IDā€™s is not safe.

@Judgewest2000, Iā€™m 100% aware of that, but am not very experienced with ViewChild and accessing the DOM. Essentially, Iā€™m building a map app knowing Iā€™ll have to reverse engineer those weaknesses eventually.

Would you be willing to post a quick example of using ViewChild to access an

<ion-searchbar [(ngModel)]="address" (ionInput)="getResults($event)"></ion-searchbar>

?
If you find the time it would be immensely helpful. Iā€™m struggling to put the pieces together in this area.

Iā€™ll owe you 20 bucks.

And honestly, your 2 cents on the subject might be more valueable than an example. I can copy paste all day long. Perhaps your perspective on how ViewChild and that specific element interact would be best.

The $20ā€™s on the table either way

Right letā€™s go back up one levelā€¦

What are you trying to achieve??

Good thinkingā€¦
I have an app, googlemaps is working, autocomplete is working, google places: working.

But, my code contains things like this:

import {etc..}

export class MapPage {
_sbElement: HTMLInputElement;
constructor() {
}
ionViewDidLoad() {
this._sbElement = document.getElementsByClassName('searchbar-input')[0];
let autoPlaces = new google.maps.places.Autocomplete(this.sbElement);
  }
}

Thatā€™s a rough estimate of a working example Iā€™ve put together.
Plus a bunch of other stuff of course.

How would I go about using ViewChild to achieve the same result in a safe manner?
As in, referencing the search bar and passing that reference to autoPlaces, but without document.getElementsByClassName

Sorry. Have to edit

this._sbElement = document.getElememtsByClassName('searchbar-input')[0];

Itā€™s actually

this._sbElement = <HTMLInputElement>document.getElememtsByClassName('searchbar-input')[0];

Howdy,

Iā€™ve got a sleeping baby on me atm so Iā€™ll keep it brief :slight_smile:

Two things:

  • Obviously Ionic does a lot of wrapping of native elements so your mileage may vary as to how successful itā€™ll be using them for this specific case. You might find it easier working with a regular element with only slight scss trickery.

  • Regardless of the type of element you settle on you you will need to add a hashtag to the elementā€¦

<input type="text" #searchbar />

Then to reference it you use the ViewChildā€¦

@ViewChild('searchbar') searchBar: ElementRef;

Then to get the element itselfā€¦

useElement(){
   const element = this.searchBar.nativeElement as HTMLInputElement;
   let autoPlaces = new google.maps.places.Autocomplete(element);
}

Let me know if thatā€™s enough or not.

1 Like

Definitely a big help. A different perspective was necessary. Mine sucked on this topic I guess. 2 questions.

  1. When you type
@ViewChild('searchbar') searchBar: ElementRef;    

Is searchBar: ElementRef; basically the ViewChild version of

word: string;     ?
  1. Iā€™m referencing the DOM, but am typing my items in a pretty solid manner. Does remaining vigilant with typing reduce the negative impact of referencing the DOM to a point that using @ViewChild becomes unnecessary or even less necessary?
searchBarInput: HTMLInputElement;
searchBarResults: HTMLCollectionOf<Element>;

thanks man. Appreciate any response and wisdom.

Sorry, not getting the first questionā€¦ do you mean what are you eventually getting back from the ViewChild? If so youā€™re getting a reference to the HTML element itself. So you can do elementName.innerHTML = ā€˜whateverā€™;

Second question:
The real world problem is no different than any other kind of reuse issues in any framework. If you put this stuff into a component with an Id or class as a reference, and you end up using that component multiple times like in a loop or whatever, itā€™s game over, youā€™ll select the wrong one etc all the time.

You might think you ā€˜neverā€™ will. You will!!! Might not be with this component but with another.

Also keep in mind when you navctrl.push to another page, the previous pageā€™s contents are still in the dom, and thatā€™s a real world obvious problem.

1 Like

Sorry. A sleepless night is seriously effecting my communication skills. You answered what I was asking with question 1.

And, as far as question 2, thanks for the advice. It is appreciated. Good points all around.

Thank you.

Donā€™t forget to thumb up or mark as solution where appropriate :stuck_out_tongue:

I didnā€™t even know I could thumb up! Iā€™ll do so.

You scored one more like, sir. Thanks much.
Can one literally thumb-up a post?

@Judgewest2000, Iā€™ve been able to completely gut my app of direct DOM references using ViewChild and ViewChildren, and made some real progress in combining google maps PlacesService and Autocomplete. So, Thank you again for the chat earlier.

1 Like

If that $20 is on the table give it to some charity in Las Vegas re the recent shootings.

1 Like

Consider it done, @Judgewest2000. If there is a specific charity youā€™d like to see benefit, let me know. If not, Iā€™ll find one on my own. Great random opportunity to do something good for others.

Cheers

1 Like

Any you like thatā€™s relevant.

This gofundme looks pretty good for the cause.

Thank you

As I was going through ElementRef in Angular Documentation ā€œhttps://angular.io/api/core/ElementRefā€, It was mentioning some security issue.Is it still preferred to access DOM that way?

hahaha
I didnā€™t forget you.

Didnā€™t forget what??