Tips for refreshing the direction route in google-maps-react

I have an array of coordinates, and when I add a new coordinate to the array, I want the route direction on the map to update accordingly.

This is the code snippet from my googlemap.js file:

/* global google */
import React, { Component } from "react";
import { Map, GoogleApiWrapper } from "google-maps-react";
import "./config";
import Router from 'next/router';


class MapContainer extends React.Component {


  constructor(props) {
    super(props);
    this.handleMapReady = this.handleMapReady.bind(this);
  }

  handleMapReady(mapProps, map) {
    this.calculateAndDisplayRoute(map);
  }
  

calculateAndDisplayRoute(map) {
  const directionsService = new google.maps.DirectionsService();
  const directionsDisplay = new google.maps.DirectionsRenderer();
  directionsDisplay.setMap(map);

  const waypoints = this.props.data.map((item) => {
    return {
      location: { lat: item.lat, lng: item.lng },
      stopover: true,
    };
  });
  const origin = waypoints.shift().location;
  const destination = waypoints.pop().location;

  directionsService.route(
    {
      origin: origin,
      destination: destination,
      waypoints: waypoints,
      travelMode: "DRIVING",
    },
    (response, status) => {
      if (status === "OK") {
        directionsDisplay.setDirections(response);
      } else {
        window.alert("Directions request failed due to " + status);
      }
    }
  );
}
  render() {
   
    return (
      <div className="map-container"  >
        <Map
          google={this.props.google}
          className={"map"}
          zoom={14}
          initialCenter={{
            lat: 14.5995,
            lng: 120.9842,
          }}
          onClick={this.handleMapClick}
          onReady={this.handleMapReady}
        />
      </div>
    );
  }
}

export default GoogleApiWrapper({
  apiKey: "",
  libraries: [],
})(MapContainer);

I'm exploring this plugin as an alternative to react-google-maps which is no longer actively maintained. It's a learning process for me as I navigate through implementing this in my project.

Answer №1

If you possess an array consisting of coordinates and desire to showcase the directions on a map corresponding to these coordinates, you must designate the first coordinate as the start, label the last coordinate as the destination, and assign the coordinates in between as your waypoints.

Subsequently, when adding a new coordinate to the array, it is crucial to incorporate the previous last coordinate in your waypoint while designating the newly added coordinate as the destination.

Presented below is a demonstrative code where Google Place Autocomplete is utilized. You have the advantage of inputting a place, receiving suggestions, selecting a place from the suggestion list whereby its coordinates are acquired, and then pushing them into the array.

Please refer to the code snippet provided:

import React, { Component } from "react";
import { Map, InfoWindow, Marker, GoogleApiWrapper } from "google-maps-react";
import "./style.css";
import "./config";
export class MapContainer extends Component {

  //function triggered once the map is loaded
  onMapReady = (mapProps, map) => {
    let coords = [];
    let waypoints = [];
    
    //placing data from the config file into an array
    {
      places.map((place) => coords.push({ lat: place.lat, lng: place.lng }));
    }

    //creating instances of directions service and directions renderer
    const directionsService = new google.maps.DirectionsService();
    const directionsDisplay = new google.maps.DirectionsRenderer();
    
    //assigning directions renderer to display on the map
    directionsDisplay.setMap(map);
    
    //Setting the initial coordinate in the array as the start/origin 
    let start = { lat: coords[0].lat, lng: coords[0].lng };
    
    //Designating the final coordinate in the array as the end/destination
    let end = {
      lat: coords[coords.length - 1].lat,
      lng: coords[coords.length - 1].lng,
    };
    
    //Including all coordinates between the first and last ones as waypoints
    for (let i = 1; i < coords.length - 1; i++) {
      waypoints.push({
        location: { lat: coords[i].lat, lng: coords[i].lng },
        stopover: true,
      });
    }
    
    //Creating directions requests
    let request = {
      origin: start,
      waypoints: waypoints,
      destination: end,
      travelMode: "DRIVING",
    };
    
    //displaying results on the directions renderer
    directionsService.route(request, function (result, status) {
      if (status == "OK") {
        directionsDisplay.setDirections(result);
      }
    });

    //setting up autocomplete input
    let card = document.getElementById("pac-card");
    let input = document.getElementById("pac-input");
    map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
    let autocomplete = new google.maps.places.Autocomplete(input);
    
    //Binding the map's bounds to the autocomplete object
    autocomplete.bindTo("bounds", map);
    
    //Specifying the fields to return upon selecting a place
    autocomplete.setFields(["address_components", "geometry", "icon", "name"]);
    
    //listener for the places input
    autocomplete.addListener("place_changed", function () {
      
      console.log(waypoints);
      let place = autocomplete.getPlace();
      if (!place.geometry) {
        window.alert("No details available for input: '" + place.name + "'");
        return;
      }
      
      //Adding the previous last coordinate in the array as part of the waypoint
      waypoints.push({
        location: {
          lat: coords[coords.length - 1].lat,
          lng: coords[coords.length - 1].lng,
        },
        stopover: true,
      });
      
      //Inserting the Place Autocomplete coordinate in the coords array
      coords.push({
        lat: place.geometry.location.lat(),
        lng: place.geometry.location.lng(),
      });
      
      //Updating the end/destination with the Place Autocomplete result coordinate
      end = place.geometry.location;
      
      //modifying the request
      request = {
        origin: start,
        waypoints: waypoints,
        destination: end,
        travelMode: "DRIVING",
      };
      
      //issuing a new directions request
      directionsService.route(request, function (result, status) {
        if (status == "OK") {
          directionsDisplay.setDirections(result);
        }
      });
    });
  };

  render() {
    return (
      <div>
        <Map
          className="map"
          initialCenter={{ lat: 14.6091, lng: 121.0223 }}
          google={this.props.google}
          onClick={this.onMapClicked}
          onReady={this.onMapReady}
          style={{ height: "100%", position: "relative", width: "100%" }}
          zoom={8}
        ></Map>
        <div className="pac-card" id="pac-card">
          <div>
            <div id="title">Add new point</div>

            <div id="pac-container">
              <input
                id="pac-input"
                type="text"
                placeholder="Enter a location"
              />
            </div>
          </div>
        </div>
        <div style={{ width: 500, height: 500 }} id={this.props.id} />
        <div id="infowindow-content">
          <img src="" width="16" height="16" id="place-icon" />
          <span id="place-name" className="title"></span>
          <br />
          <span id="place-address"></span>
          <br />
          <span id="place-coord"></span>
        </div>
      </div>
    );
  }
}

//connecting component with Google API
export default GoogleApiWrapper({
  apiKey: "YOUR_API_KEY",
  version: "3.40",
})(MapContainer);

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

Issue with React not displaying JSX when onClick Button is triggered

I've recently started learning React and I'm facing a problem that I can't seem to figure out. I have a basic button, and when it's clicked, I want to add another text or HTML element. While the console log statement is working fine, th ...

Images stored locally are not appearing in React JS applications

I'm currently exploring React JS and Material UI to develop a dynamic web application. I'm attempting to link a local image using 'url(${process.env.PUBLIC_URL})' but unfortunately, the image is not showing up for some unknown reason. ...

Creating a Configuration File for POST Requests in NodeJS Express

In my NodeJS application using Express, I currently have a hardcoded method for handling URL POST Request Calls and responding with JSON Files. This means that every time I need to add more POST Request Inputs or specify which JSON File to use, I have to m ...

Is there a bug in Safari 8.0 related to jQuery and backslashes?

I am using Mac OS 10.10 Yosemite and Safari 8.0. Attempting to read an XML (RSS) file: <content:encoded>bla bla bla</content:encoded> The Javascript Ajax method I am using is: description:$(valeur).find('content\\:encoded&apo ...

A superior method for implementing CSS keyframe transitions

Currently, I am utilizing the Rico St.Cruz brilliant query.transit library for my work. However, I need to make some changes involving classes instead of CSS transitions. Although I am not very confident in CSS transitions, I attempted to replace: JS: $ ...

React Component State in JavaScript is a crucial aspect of building

What happens when the expression [...Array(totalStars)] is used within a React Component? Is the result an array with a length of 5, and what are the specific elements in this array? We appreciate your response. class StarRating extends Component { ...

What are Fabric.js tools for "Drop Zones"?

Has anyone successfully created a "drop zone" similar to interact.js using fabric.js? I haven't had the chance to experiment with it myself. I have some ideas on how I could potentially implement it, but before diving in, I wanted to see if anyone el ...

Anticipated input should be in the format of '_item_ in _collection_[ track by _id_]' but instead received

Having trouble with ng-repeat in AngularJS, only showing first element and getting a console error: Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '”pm'. angular.module('DataCabinet') .c ...

The backend API does not receive the correct value from the checkbox

I'm having an issue with my registration page in ReactJS. There is a checkbox field called isadult. After clicking on the Register button and saving the data to a MongoDB database, the value of isadult shows up as [Object object] instead of True or Fa ...

Creating an array of logos in ReactJS with the help of TailwindCSS

After seeing multiple implementations of this feature, I find myself struggling to search for a solution. I can only access the HTML and CSS through inspecting elements, wondering if others are facing the same issue as me. Typically, we aim to implement t ...

Managing user access and permissions using JavaScript on the front end

I find myself in a situation where I am working on developing a single page application: The majority of the operations rely on ajax requests. Depending on the user's login status (admin, regular user, visitor), different components need to be displ ...

The curious case of jQuery.parseJSON() failing to decode a seemingly valid Json string on a Windows-based server

I am currently running a WordPress JavaScript function code on a Linux server that also includes a PHP function called "get_form_data". jQuery.ajax({ type: "POST", url: MyAjax.ajaxurl, data: {action: "get_fo ...

Creating various functions for Joomla's AJAX component development

My component is currently working smoothly with AJAX and mootools. The view.raw.php file contains only one function called display. I've been attempting to add other functions within the component that can be accessed through AJAX, but have been facin ...

What causes npm to be undefined when I verify node?

screenshot of my terminal Currently learning react and encountered an issue while checking if npm downloaded properly. It appears to be running fine, but for some reason, after I enter 'node' and then try to check npm again, I get an error messa ...

Vuejs is throwing an uncaught promise error due to a SyntaxError because it encountered an unexpected "<" token at the beginning of a JSON object

I am currently attempting to generate a treemap visualization utilizing data sourced from a .json file. My approach involves employing d3 and Vue to assist in the implementation process. However, upon attempting to import my data via the d3.json() method ...

Looking to verify the existence of a div using jQuery once other jQuery functions have executed and created HTML?

Is there a way to verify if a specific element exists within newly added HTML after clicking a button? I attempted this code snippet: $(document).on('click', '#add-html-code', function() { if ($('#something').length ...

difficulty in making an https request

My application was developed using OFFICEjs and was functioning properly on LOCALHOST. However, last week it suddenly started throwing an error message - "XHR Error." This issue arose out of nowhere, as I hadn't made any changes to the code over the w ...

How do I find the child elements within a parent node?

I am currently utilizing a jquery plugin that has rendered the following HTML layout in the browser: <html> <body> <div class="mce-container-body"> ... <input type="text" id="textedit01"> ... </di ...

Conceal the scroll bar while the page preloader is active

Is there a way to hide the scroll bar while the preloader is loading on a webpage? I want to prevent users from scrolling until the preloader disappears. I have tried using CSS and setting the body overflow to hidden, but it's not working as expected. ...

"Exploring the process of looping through a JSON object following an asynchronous retrieval of JSON data using

I am facing an issue while trying to iterate through a JSON object in jQuery after fetching it asynchronously. I have a function called 'listFiles' that uses async to successfully retrieve a file list from a directory (dir) by calling an API endp ...