Search code examples
reactjscreate-react-appgoogle-distancematrix-apireact-google-maps

How do I use Distance Matrix API in ReactJS using @react-google-maps/api?


I am using the above package and I can't find proper documentation to implement the code. Currently, this is my code:

import React, { Component } from "react";
import { GoogleMap, DistanceMatrixService } from "@react-google-maps/api";
class ExampleDirections extends Component {
  state = {
    response: null,
    travelMode: "DRIVING",
    origin: "",
    destination: "",
  };

  distanceCallback = (response) => {
    console.log("Hello");
    console.log(response);

    if (response !== null) {
      if (response.status === "OK") {
        this.setState(() => ({
          response,
        }));
      } else {
        console.log("response: ", response);
      }
    }
  };

  checkDriving = ({ target: { checked } }) => {
    checked &&
      this.setState(() => ({
        travelMode: "DRIVING",
      }));
  };

  getOrigin = (ref) => {
    this.origin = ref;
  };

  getDestination = (ref) => {
    this.destination = ref;
  };

  onClick = () => {
    if (this.origin.value !== "" && this.destination.value !== "") {
      this.setState(() => ({
        origin: this.origin.value,
        destination: this.destination.value,
      }));
    }
  };

  onMapClick = (...args) => {
    console.log("onClick args: ", args);
  };

  render = () => (
    <div className="map">
      <div className="map-settings">
        <hr className="mt-0 mb-3" />

        <div className="row">
          <div className="col-md-6 col-lg-4">
            <div className="form-group">
              <label htmlFor="ORIGIN">Origin</label>
              <br />
              <input
                id="ORIGIN"
                className="form-control"
                type="text"
                ref={this.getOrigin}
              />
            </div>
          </div>

          <div className="col-md-6 col-lg-4">
            <div className="form-group">
              <label htmlFor="DESTINATION">Destination</label>
              <br />
              <input
                id="DESTINATION"
                className="form-control"
                type="text"
                ref={this.getDestination}
              />
            </div>
          </div>
        </div>

        <div className="d-flex flex-wrap">
          <div className="form-group custom-control custom-radio mr-4">
            <input
              id="DRIVING"
              className="custom-control-input"
              name="travelMode"
              type="radio"
              checked={this.state.travelMode === "DRIVING"}
              onChange={this.checkDriving}
            />
            <label className="custom-control-label" htmlFor="DRIVING">
              Driving
            </label>
          </div>
        </div>

        <button
          className="btn btn-primary"
          type="button"
          onClick={this.onClick}
        >
          Build Route
        </button>
      </div>

      <div className="map-container">
        <GoogleMap
          id="map"
          mapContainerStyle={mapContainerStyle}
          zoom={14}
          center={center}
          options={options}
        >
          <DistanceMatrixService
            options={{
              destinations: this.state.destination,
              origins: this.state.origin,
              travelMode: this.state.travelMode,
            }}
            callback={this.distanceCallback}
          />
          )}
        </GoogleMap>
      </div>
    </div>
  );
}

export default ExampleDirections;

Am getting the following error with this code:

InvalidValueError: in property origins: not an Array

I want to use all the other services like directions, places, autocomplete together later. Now am trying to work things individually and I am having a problem only with this.

Better alternatives to the package are also fine. THANK YOU

CONTINUED

So I got my problem solved with the answer from below. But, now when I try to save the response in a state, the API is called endlessly. Down below is my code. THanks for the help.

<DistanceMatrixService
            options={{
              destinations: [{ lat: 1.296788, lng: 103.778961 }],
              origins: [{ lng: 72.89216, lat: 19.12092 }],
              travelMode: "DRIVING",
            }}
            callback={(res) => {
              console.log("RESPONSE", res);
              this.setState({
                totalTime: res.rows[0].elements[0].duration.text,
                totalDistance: res.rows[0].elements[0].distance.text,
              });
            }}
          />

It works fine when I only call console.log or when I declare variables and save values in them. But, when I try using setState, this issue occurs.


Solution

  • I've been having a hard time figuring out the revamped react-google-maps as well.I got the distance matrix working as follows:

    <DistanceMatrixService
     options={{
               destinations: [{lat:1.296788, lng:103.778961}],
               origins: [{lng:103.780267, lat:1.291692}],
               travelMode: "DRIVING",
             }}
     callback = {(response) => {console.log(response)}}
    />
    

    Ensure your destinations and origins are arrays and don't forget to enable all the necessary APIs.