0

So, I was just trying to get current location by using navigator.getlocation.getCurrentLocation method in Lightning Web Components. When I check if(navigator.getlocation), this returns true.

But when use the method, it always gives me an error like

"afterRender threw an error in 'c:sampleMapComponent' [Cannot read property 'length' of undefined]".

Below is my code of JS file.

/* eslint-disable no-console */
import { LightningElement, track } from 'lwc';

export default class SampleMapComponent extends LightningElement {
    @track mapMarkers;

    get findMe() {
        navigator.geolocation.getCurrentPosition(this.success, this.error);
        return this.mapMarkers;
    }

    success(position) {
        if (position) {
            console.log('position -> ' + position);
            this.mapMarkers = [
                {
                    location: {
                        'Latitude': position.coords.latitude,
                        'Longitude': position.coords.longitude
                    },
                    title: "My Location",
                },
            ]
        }

    }

    error() {
        console.log('Failed');
    }
}

Template:

<template>
<h1>Current Location</h1>
<template if:true={mapMarkers}>
    <lightning-map map-markers={mapMarkers}></lightning-map>
</template>

Error:

enter image description here

Please let me know what am I doing wrong..I am calling findMe() method from template (from map-markers of lightning-map)

2
  • Are you sure this is your complete code? I don't see the if condition that you have mentioned and length being used anywhere in the code.
    – Jayant Das
    Commented May 24, 2019 at 20:45
  • Hi Jayant, I've removed the if condition. I just wanted to check if navigator... is allowed in lwc or not. It returned true. And I didnt put length nowhere in my code either. I've edited my question with screenshot of error and template. Commented May 24, 2019 at 21:50

4 Answers 4

1

findMe is returning a null value, because the code to get the geocode is asynchronous. Without seeing your template, I can't advise a perfect fix, but you might start with this:

/* eslint-disable no-console */
import { LightningElement, track } from 'lwc';

export default class SampleMapComponent extends LightningElement {
    // Default is no markers
    @track mapMarkers = [];

    // Called when component is displayed
    connectedCallback() {
        navigator.geolocation.getCurrentPosition(this.success, this.error);
    }

    // Update the map marker
    success(position) {
        if (position) {
            console.log('position -> ' + position);
            this.mapMarkers = [
                {
                    location: {
                        'Latitude': position.coords.latitude,
                        'Longitude': position.coords.longitude
                    },
                    title: "My Location",
                },
            ]
        }

    }

    error() {
        console.log('Failed');
    }
}
1
  • I've changed the JS file as you said. Now, the 'length of undefined....' error is gone (probably cause we have initialised mapMarkers to be []) but it just displays a map without any markers...can you please comment where am I going wrong...(I've also added the template file in the question) Commented May 24, 2019 at 22:20
1

The answer of @sfdxfox is almost correct, the problem is that success function is being executed with the this of the navigator.geolocation, instead of the c:sampleMapComponent.

You can get the correct functionality binding the current this to the callback function with callbackFunction.bind(this)

// Called when component is displayed
    connectedCallback() {
        navigator.geolocation.getCurrentPosition(this.success.bind(this), this.error.bind(this));
    }

    // Update the map marker
    success(position) {
        if (position) {
            console.log('position -> ' + position);
            this.mapMarkers = [
                {
                    location: {
                        'Latitude': position.coords.latitude,
                        'Longitude': position.coords.longitude
                    },
                    title: "My Location",
                },
            ]
        }

    }

or use a lambda function, which preserves the this, in my opinion, the second one is the best approach as is a method that is only going to be called as an event handler of that specific line, avoiding it to be called from out of there

// Called when component is displayed
    connectedCallback() {
        navigator.geolocation.getCurrentPosition(position => { /** handler */ }, error => { /** handler */ });
    }
0

Extra comma , is found in your mapMarkers list. Remove and try it again.

},

this.mapMarkers = [
            {
                location: {
                    'Latitude': position.coords.latitude,
                    'Longitude': position.coords.longitude
                },
                title: "My Location",
            },
        ]
-1

@sfdcfox Can we get City, country, state, postal code from this? Like if I try to get my current location its using the Latitude and Longitude. However, I also want to fetch the Address Detail for that selected address. Is there any way to do that?

            location: {
                'Latitude': position.coords.latitude,
                'Longitude': position.coords.longitude
            },

Like in the above code snippet we are fetching the Lat and Long. So can we get the Address Detail from that lat and long? and atleast print it in the console?

1
  • 1
    If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review
    – Derek F
    Commented Apr 26, 2022 at 11:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .