Google Maps Places Autocomplete - Uncaught TypeError: Cannot read property 'getPlace' of undefined

房东的猫 提交于 2019-12-14 00:35:18

问题


setAutocomplete() {
    this.originPlaceId = null;
    this.destinationPlaceId = null;
    this.travelMode = google.maps.TravelMode.WALKING;
    this.directionsDisplay.setMap(this.map);

    this.setMapControls(this.map);

    this.setupClickListener('changemode-walking', google.maps.TravelMode.WALKING);
    this.setupClickListener('changemode-transit', google.maps.TravelMode.TRANSIT);
    this.setupClickListener('changemode-driving', google.maps.TravelMode.DRIVING);

    console.log(this.originInput);
    this.originAutocomplete = new google.maps.places.Autocomplete(this.originInput);
    this.originAutocomplete.bindTo('bounds', this.map);
    console.log(this.originAutocomplete);
    this.originAutocomplete.addListener('place_changed', function() {
        console.log(this.originAutocomplete);
        var place = this.originAutocomplete.getPlace();
        console.log("here", place);
        if (!place.geometry) {
            window.alert("Autocomplete's returned place contains no geometry");
            return;
        }
        this.expandViewportToFitPlace(this.map, place);

        // If the place has a geometry, store its place ID and route if we have
        // the other place ID
        this.originPlaceId = place.place_id;
        this.route(this.directionsService, this.directionsDisplay);
    });

    this.destinationAutocomplete = new google.maps.places.Autocomplete(this.destinationPlaceInput);
    this.destinationAutocomplete.bindTo('bounds',this.map);
    this.destinationAutocomplete.addListener('place_changed', function() {
        var place = this.destinationAutocomplete.getPlace();
        if (!place.geometry) {
            window.alert("Autocomplete's returned place contains no geometry");
            return;
        }
        this.expandViewportToFitPlace(this.map, place);

        // If the place has a geometry, store its place ID and route if we have
        // the other place ID
        this.destinationPlaceId = place.place_id;
        this.route(this.directionsService, this.directionsDisplay);
        //this.getNearbyPlaces(this.destinationPlaceId, 5000);
    });
};
setMapControls(map) {
    this.originInput = document.getElementById('origin-input');
    this.destinationPlaceInput = document.getElementById('destination-input');
    this.modes = document.getElementById('mode-selector');

    map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.originInput);
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.destinationPlaceInput);
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.modes);
};
<input id="origin-input" class="controls" type="text" force-selection="true" placeholder="Enter an origin location">
<input id="destination-input" class="controls" type="text" force-selection="true" placeholder="Enter a destination location">
<div id="mode-selector" class="controls">
    <input type="radio" name="type" id="changemode-walking" checked="checked">
    <label for="changemode-walking">Walking</label>
    <input type="radio" name="type" id="changemode-transit">
    <label for="changemode-transit">Transit</label>
    <input type="radio" name="type" id="changemode-driving">
    <label for="changemode-driving">Driving</label>
</div>
<div id="directionsList"></div>
<div id="map_canvas"></div>

I have these functions which are supposed to give me the directions A to B from Google Maps Places from the input fields (originInput and destinationPlaceInput).

After I select an input I have this error in console:

Uncaught TypeError: Cannot read property 'getPlace' of undefined

This error is thrown after the "place_changed" event triggers.


回答1:


Inside the place_changed-callback the keyword this points to the object which has been triggered the event.

so you may simply use

var place = this.getPlace();

instead of

var place = this.destinationAutocomplete.getPlace();



回答2:


How to keep the context/this of the controller?

tldr:

Create a function that returns a function with the context:

this.searchBox.addListener('places_changed', ((that) => () => this.placesChanged(that))(this));

Explanation

Like Dr.Molle points out: this points to the object which has triggered the event, namely the element on which you want to add an event listener on.

The addListener takes a function declaration. To keep access on your controller's this, you could also create a closure that passes the controller's this into the function, like so:

this.searchBox.addListener('places_changed', ((that) => () => this.placesChanged(that))(this));

Here I defined a function that takes a parameter called that, and upon execution returns a function that contains the this. It is a closure because the inner function's scope keeps a reference to the that variable from the outer functions scope (and other variables that could get passed to this.placesChanged).

Now if a event places_changed is emitted, the function declaration is ran. I am still able to change properties on the that variable inside the this.placesChanged function. This is possible because in objects are passed by reference (whereas primitive types are passed by values).



来源:https://stackoverflow.com/questions/37230901/google-maps-places-autocomplete-uncaught-typeerror-cannot-read-property-getp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!