1

So i have the following functional component that works fine. What i want to do is cache the results so i am not hitting the api over and over again for same search term.

import React, { useState, useEffect, useRef } from "react";
import currentSession from "../currentSession";

let autoComplete;

const loadScript = (url, callback) => {
  let script = document.createElement("script");
  script.type = "text/javascript";

  if (script.readyState) {
    script.onreadystatechange = function () {
      if (script.readyState === "loaded" || script.readyState === "complete") {
        script.onreadystatechange = null;
        callback();
      }
    };
  } else {
    script.onload = () => callback();
  }

  script.src = url;
  document.getElementsByTagName("head")[0].appendChild(script);
};

function handleScriptLoad(updateQuery, autoCompleteRef) {
  autoComplete = new window.google.maps.places.Autocomplete(
    autoCompleteRef.current,
    { types: ["(cities)"] }
  );
  autoComplete.setFields(["address_components", "formatted_address"]);
  autoComplete.addListener("place_changed", () =>
    handlePlaceSelect(updateQuery)
  );
}

async function handlePlaceSelect(updateQuery) {
  const addressObject = autoComplete.getPlace();
  const query = addressObject.formatted_address;
  updateQuery(query);
}

function SearchLocationInput(props) {
  const [query, setQuery] = useState("");
  const autoCompleteRef = useRef(null);

  useEffect(() => {
    loadScript(
      "https://maps.googleapis.com/maps/api/js?key=" +
        currentSession.getGoogleApiKey() +
        "&libraries=places",
      () => handleScriptLoad(setQuery, autoCompleteRef)
    );
  }, []);

  return (
    <div className="search-location-input">
      <input
        ref={autoCompleteRef}
        onChange={(event) => {
          props.onCityChange(event.target.value);
          setQuery(event.target.value);
        }}
        placeholder="Enter a City"
        value={query}
      />
    </div>
  );
}

export default SearchLocationInput;

I am assuming the request is occurring in the loaded script so i am not sure how i can accomplish this?

Maxqueue
  • 2,194
  • 2
  • 23
  • 55
  • What did you end up doing? – Ryan Oct 17 '20 at 01:23
  • 2
    Since this was not possible ended up using my own autocomplete and using local storage to cache results. So for example if user typed "ab" api would only get called if cached results were not in local storage. Writing my own autocomplete component was pretty simple and gave me full control on how it behaved. – Maxqueue Oct 17 '20 at 13:53

0 Answers0