Avoid placing function declarations within blocks

My JavaScript code (shown below) is quite messy and has a persistent error that I can't seem to fix. The issue lies within the showPosition function, where I have nested a function within another function, which is not a recommended practice. I am relatively new to working with JavaScript, so please excuse me if this seems like a basic question. I've also included a link to a jsFiddle showcasing my code conundrum (http://jsfiddle.net/dnUTx/).

When testing the code on jsFiddle, I encounter an error on line 25 stating 'function declarations should not be placed in blocks'.

Any assistance in resolving this issue would be highly appreciated.

// JavaScript Document

var x = document.getElementById("info");

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.watchPosition(showPosition, showError, clearWatch, {
            enableHighAccuracy: true,
            maximumAge: 30000,
            timeout: 30000
        });
    } else {
        x.innerHTML = "Your browser does not support the geolocation API.";
    }
}
var flightPathCoordinates = [];
var lat1, lng1, first_check = false;

function showPosition(position) {
    if (!first_check) {
        lat1 = position.coords.latitude;
        lng1 = position.coords.longitude;
        first_check = true;
    } else {
        function distanceFrom(points) {
            var lat1 = points.lat1;
            var radianLat1 = lat1 * (Math.PI / 180);
            var lng1 = points.lng1;
            var radianLng1 = lng1 * (Math.PI / 180);
            var lat2 = points.lat2;
            var radianLat2 = lat2 * (Math.PI / 180);
            var lng2 = points.lng2;
            var radianLng2 = lng2 * (Math.PI / 180);
            var earth_radius = 3959; // or 6371 for kilometers
            var diffLat = (radianLat1 - radianLat2);
            var diffLng = (radianLng1 - radianLng2);
            var sinLat = Math.sin(diffLat / 2);
            var sinLng = Math.sin(diffLng / 2);
            var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0);
            var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));
            return distance.toFixed(3);
        }
        var distance = distanceFrom({
            "lat1": lat1,
            "lng1": lng1,
            "lat2": position.coords.latitude,
            "lng2": position.coords.longitude
        });
    }
    x.innerHTML = "Latitude: " + position.coords.latitude +
        "<br>Longitude: " + position.coords.longitude +
        "<br>Accuracy: " + position.coords.accuracy +
        "<br>Altitude: " + position.coords.altitude +
        "<br>Altitude Accuracy: " + position.coords.altitudeAccuracy +
        "<br>Heading: " + position.coords.heading +
        "<br>Speed (km): " + position.coords.speed * 3.6 +
        "<br>Timestamp: " + new Date(position.timestamp).toLocaleString() +
        "<br>Distance Travelled (km): " + distance +
        "<br>Stopwatch: " + min + ":" + sec + ":" + msec;

    lat = position.coords.latitude;
    lon = position.coords.longitude;
    latlon = new google.maps.LatLng(lat, lon);
    mapholder = document.getElementById('mapholder');

    var myOptions = {
        center: latlon,
        zoom: 16,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: true,
        navigationControlOptions: {
            style: google.maps.NavigationControlStyle.SMALL
        }
    };
    var map = new google.maps.Map(document.getElementById("mapholder"), myOptions);

    //Bicycle Store
    var request = {
        location: (latlon),
        radius: '1000',
        types: ['bicycle_store']
    };
    infowindow = new google.maps.InfoWindow();
    var service = new google.maps.places.PlacesService(map);
    service.nearbySearch(request, callback);

    function callback(results, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            for (var i = 0; i < results.length; i++) {
                var place = results[i];
                createMarker(results[i]);
            }
        }
    }

    function createMarker(place) {
        var placeLoc = place.geometry.location;

        //Custom Marker 1
        var image1 = '../images/logo_marker1.png';
        var marker1 = new google.maps.Marker({
            position: place.geometry.location,
            map: map,
            icon: image1,
            title: "Bicycle Store"
        });
        google.maps.event.addListener(marker1, 'click', function () {
            infowindow.setContent(place.name);
            infowindow.open(map, this);
        });
    }

    //Bicycle Layer
    var bikeLayer = new google.maps.BicyclingLayer();
    bikeLayer.setMap(map);

    //Custom Marker 2
    var image2 = '../images/logo_marker2.png';
    var marker2 = new google.maps.Marker({
        position: latlon,
        map: map,
        icon: image2,
        title: "You are here!"
    });

    //Panoramio Layer
    var panoramioLayer = new google.maps.panoramio.PanoramioLayer();

    panoramioLayer.setUserId("7467601");
    panoramioLayer.setMap(map);
    google.maps.event.addListener(panoramioLayer, 'click', function (event) {
        var attribution = document.createTextNode(event.featureDetails.title + ": " + event.featureDetails.author);
        var br = document.createElement("br");
        var link = document.createElement("a");
        link.setAttribute("href", event.featureDetails.url);
        link.appendChild(attribution);
    });

    //Polyline Layer
    flightPathCoordinates.push(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
    var flightPath = new google.maps.Polyline({
        path: flightPathCoordinates,
        strokeColor: "#FF0000",
        strokeOpacity: 1.0,
        strokeWeight: 2
    });
    flightPath.setMap(map);
}

function showError(error) {
    switch (error.code) {
        case error.PERMISSION_DENIED:
            x.innerHTML = "User denied the request for Geolocation.";
            break;
        case error.POSITION_UNAVAILABLE:
            x.innerHTML = "Location information is unavailable.";
            break;
        case error.TIMEOUT:
            x.innerHTML = "The request to get user location timed out.";
            break;
        case error.UNKNOWN_ERROR:
            x.innerHTML = "An unknown error occurred.";
            break;
    }
}

function clearWatch() {
    navigator.geolocation.clearWatch(showPosition);
}

Answer №1

After reviewing the provided question and jsfiddle, I must say it is well-detailed and deserves recognition. Kudos to the new member who posted it!

However, there are a couple of issues that need addressing:

The utilization of the local variable distance to construct the x.innerHTML string is problematic. The variable distance is solely defined within the else statement of the if-condition.

Additionally, there is a 'function declaration' nested within a block enclosed with curly braces {}, which violates syntax rules. Blocks can only accommodate statements, not SourceElements like FunctionDeclarations.
Hence, when inside an if/else/while/for block, a 'function expression' should be used instead;
for instance:

var identifier=function(//args){//code};

This discrepancy explains the JSHint error message displayed on JSFiddle.

For a revised version adhering to JSHint validation, refer to this updated fiddle (though due to code limitations, further testing is unfeasible).

The modifications entail introducing var distance=0 as a local variable before the initial if clause in the showPosition function and converting the function declaration into a function expression within the else block.

Best of luck!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When utilizing jQuery to add a <li> element, it suddenly vanishes

? http://jsfiddle.net/AGinther/Ysq4a/ I'm encountering an issue where, upon submitting input, a list item should be created with the content from the text field. Strangely, it briefly appears on my website but not on the fiddle, and no text is appen ...

Ways to clear away adhesive header and maintain its fixed position

I've been tinkering with my website, which you can find at this link: . I used the html5 up template for it, and the template came with a sticky header. However, when the site is viewed on a smaller screen, there's an ugly gap that forms between ...

Passing references using a personalized component

So, I've encountered this issue with my code: import MuiDialog from "@mui/material/Dialog"; import { styled } from "@mui/material/styles"; const TheDialog = styled((DialogProps) => ( <MuiDialog {...DialogProps} /> ))(( ...

Using a JavaScript variable in a script source is a common practice to dynamically reference

I have a scenario where an ajax call is made to retrieve json data, and I need to extract a value from the json to add into a script src tag. $.ajax({ url: "some url", success: function(data,response){ console.log("inside sucess"); ...

Is there a way to make the primary button on the previous page function correctly again, just like it did before it was clicked?

Issue Description: I am facing an issue on the order page where I need to link the "Continue" button to a booking page. After reaching the booking page, I expect users to be able to navigate between the two pages seamlessly even when they use the browser& ...

The struggle of encoding: Making a JSON ajax call (utf-8) to convert Latin1 characters to uppercase

I've encountered a particular issue: the Javascript library I am developing utilizes JSON cross-domain requests to fetch data from a backend powered by Ruby on Rails: function getData() { $.ajaxSetup({ 'beforeSend': function(xhr) {xhr.s ...

When async is set to true in an Ajax call, the response may come

I recently developed a function that works perfectly fine when the async option is set to false. However, I am now looking to achieve the same functionality and return value but with async set to true. function Call(param, proc) { var url = "../../ ...

We were unable to locate the module '@reactflow/core' or its associated type declarations

After forking reactflow, I attempted to make some modifications but encountered a type error even without making any changes. https://i.sstatic.net/EyTZE.jpg My next step was to try "pnpm i @types/reactflow," but it did not resolve the issue. ...

Custom pagination with onSelectionModelChange in React Material UI Data Grid

Has anyone encountered a problem with using the DataGrid component's onSelectionModelChange prop? I can successfully retrieve the selected rows for a single page, but when I implement custom pagination and navigate to the next page, the previous selec ...

What is the best way to apply a JQuery UI Tooltip to a newly added element?

In my HTML file, I have included all the necessary JS and CSS files. Then I load a content page within it. Some of these content pages contain Usernames where I want to implement a tooltip feature. Here is an example of how they are structured: <user ...

What is the best way to incorporate data from a foreach method into a function call within an HTML string?

Having trouble calling a function with data from a foreach loop while generating HTML cards and buttons from an array. The issue seems to be in the renderProducts() method. /// <reference path="coin.ts" /> /// <reference path="prod ...

Unable to `.catch()` an error while utilizing Jquery.ajax().then()

My current project involves making calls to various APIs using JQuery and caching the response from each API. This cached data is then used multiple times on the page to create different dashboard widgets. The issue I'm facing is that if an API retur ...

Achieve a "upload file" button

I am trying to create an add file button within a sidebar of a standard editor. Here are the steps involved: There is a + button. When clicked, it reveals an input field. The user enters the name of the new file and presses enter on the keyboard to s ...

Manipulating the DOM results in the SWF being reloaded

Currently, I am utilizing jQuery to insert an SWF into the DOM. However, when the SWF loads and I attempt to clone or wrap it, the SWF ends up reloading. Preventing this reload is crucial for me. Here's an example: $('#test9').before(&apo ...

What is the correct syntax for declaring a variable within a switch statement in TypeScript?

How can I properly use a switch statement in TypeScript to assign a new variable a value? For example: let name: string switch(index) { case 0: name = "cat" case 1: name = "dog" .... } I keep getting the err ...

Create a minimalist Vue table design that enforces a maximum of 2 or 3 columns within

Is there a way to make my v-simple table with v-chips and v-badges align correctly in two or three column peer cell format? Here is the table for reference: https://i.sstatic.net/OFCyx.png Currently, I only have scoped styling applied: <style scoped> ...

Having trouble sending Props between components within a specific route as I keep receiving undefined values

Here is the code for the initial component where I am sending props: const DeveloperCard = ({dev}) => { return ( <Link to={{pathname:`/dev/${dev._id}`, devProps:{dev:dev}}}> <Button variant="primary">Learn More</Butt ...

React Native: Troubleshooting Issue with Shallow Copying of Nested JSON Objects

I have a JSON structure with nested objects like this: {"name", "children": [JSON objects]}. I am attempting to add a new child to the object based on a variable path, which is an array of names. Strangely, my code works fine in the Ch ...

What is the best approach for making a drawer resizable?

I am interested in making the material ui drawer resizable width using a draggable handle. Currently, I have implemented a solution that involves adding a mouse event listener to the entire application and updating the width based on the position of the ...

In order for Javascript to continue, it must first wait for a request to be completed

I have a beginner question that's been on my mind. I'm currently working on creating a wrapper for an API and I need to authenticate to receive the access token for further requests (please note, the API doesn't use OAuth). Here is a simpli ...