Calling a prop function onLocationSelect from usePlacesWidget from react google autocomplete in Location.js. All the state values i.e serviceWindowData and routes when accessed inside onLocationSelect in parent i.e handleValueChange are empty/reset to it's initial state i.e in index.js
Printing in testFunc() values are empty, In developer tool i can see the value.
This issue is happening only for this call, For all other onChange events i am not facing this issue. Have hit a road block from 3 days, Please help me out.
Location.js
import React from 'react'
import { usePlacesWidget } from 'react-google-autocomplete'
const Location = ({
error = false,
errorMessage = '',
onLocationSelect,
placeholder = 'To',
disabled,
defaultValue,
}) => {
const { ref } = usePlacesWidget({
apiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY,
onPlaceSelected: (place) => {
onLocationSelect(place, ref.current.value)
},
options: {
types: ['geocode', 'establishment'],
// types: ['(regions)'],
componentRestrictions: { country: 'us' },
},
})
const handleOnBlur = () => {
if (!ref.current.value) {
onLocationSelect(!ref.current.value)
}
}
return (
<div className="w-full">
<div className="relative mb-4">
<label className={'dropdown_field'}>
<input
ref={ref}
placeholder={' '}
disabled={disabled}
defaultValue={defaultValue}
onBlur={handleOnBlur}
/>
<span className="label_bl">{placeholder}</span>
</label>
<div
className={
error
? 'bl-input__helper-text bl-input__helper-text--error'
: 'bl-input__helper-text'
}
>
{errorMessage}
</div>
<img
src="/media/ic_place.svg"
alt="place"
className="absolute top-4 right-4"
/>
</div>
</div>
)
}
export default Location
index.js
import { useState, useEffect } from "react";
import { PrimaryBtn } from "../../../lib/button/Button";
import DateInput from "../../TrainSearchWidget/dateinput";
import { changeDateFormat } from "../../../utilities/helperFunctions";
import DateComponent from "../DateComponent";
import { trainSearchWidget } from "constants/trainSearchWidget";
import Location from "components/Forms/Location";
import PassengerDropDown from "components/BrightlinePlus/PassengersDropdown";
import { d2dPassengers } from "constants/brightlineplus";
import TimePicker from "components/BrightlinePlus/TimePicker.js";
import moment from "moment";
import { DATE_FORMAT } from "utilities/Constants";
import Geocode from "react-geocode";
import { fetchServiceWindow } from "services/product";
import { useUser } from "../../../store/User";
const FROM = "From";
const TO = "To";
const Door2DoorService = ({
data,
isPlusDetailPage = false,
callback,
dateCompClass = "lg:left-44p",
loading,
}) => {
const user = useUser();
const [serviceWindowData, setServiceWindowData] = useState([]);
const [routes, setRoutes] = useState([]);
const [errors, setErrors] = useState({
origin: { error: false, errorMessage: "" },
destination: { error: false, errorMessage: "" },
});
const [showDateRange, setShowDateRange] = useState(false);
const [dateValue, setDateValue] = useState();
const [passengersOptions, setPassengersOptions] = useState(
d2dPassengers.passengers
);
const [serviceOptions, setServiceOptions] = useState(
d2dPassengers.serviceRequests
);
const dateRangeToggle = (val) => {
setShowDateRange(val);
};
useEffect(() => {
getServiceData();
},[]);
useEffect(() => {
if (!isPlusDetailPage) {
if (navigator.geolocation) {
const options = {
enableHighAccuracy: true,
};
Geocode.setApiKey(process.env.NEXT_PUBLIC_GOOGLE_API_KEY);
navigator.geolocation.getCurrentPosition(
function (position) {
let newData = d2dData.origin;
newData.lat = position.coords.latitude;
newData.lng = position.coords.longitude;
setD2dData((prev) => {
return { ...prev, origin: newData };
});
Geocode.fromLatLng(
position.coords.latitude,
position.coords.longitude
).then(
(response) => {
const address = response.results[0].formatted_address;
let newData = d2dData.origin;
newData.address = address;
setD2dData((prev) => {
return { ...prev, origin: newData };
});
},
(error) => {
console.error(error);
}
);
},
function (err) {
console.error(err?.message);
},
options
);
} else {
// error case
}
}
}, []);
const getServiceData = async () => {
let res = await fetchServiceWindow();
setServiceWindowData(res?.data);
console.log(res?.data);
};
const swapDestinations = () => {
setD2dData((prev) => {
return {
...prev,
origin: d2dData.destination,
destination: d2dData.origin,
};
});
};
const handleValueChange = (value, type) => {
let data = d2dData[type];
data.lat = value?.geometry?.location?.lat();
data.lng = value?.geometry?.location?.lng();
data.address = value?.formatted_address;
console.log(type === "origin");
console.log(data.lat);
console.log(data.lng);
if (type === "origin" && data.lat && data.lng) {
testFunc();
// let res = getNearestFromStationUsingDistanceMatrix();
}
setD2dData((prev) => {
return { ...prev, [type]: data };
});
dateRangeToggle(false);
};
const testFunc = () => {
console.log(serviceWindowData);
console.log(routes);
};
return (
<>
<div
className={`text-base text-bl-black pt-px ${
isPlusDetailPage && "hidden"
}`}
>
{
"Enjoy a door-to-door experience. Brightline+ includes your train ride + transportation to and from the station."
}
</div>
<div
className={`grid lg:gap-3 lg:pt-0-938 relative ${
isPlusDetailPage ? "grid-cols-6" : "grid-cols-5"
}`}
>
<div className="col-span-12 mb-2 mt-4 relative lg:m-0 lg:col-span-1">
<Location
error={errors.origin.error}
errorMessage={errors.origin.errorMessage}
defaultValue={d2dData.origin.address}
placeholder={FROM}
img="/media/ic_origin.svg"
onLocationSelect={(val) => handleValueChange(val, "origin")}
/>
<div
onClick={swapDestinations}
className="bl-ts-btnswitch__h hidden lg:flex lg:mt-2"
>
<span></span>
</div>
<div
onClick={swapDestinations}
className="bl-ts-btnswitch__v lg:hidden h-14"
>
<span className="h-2-188"></span>
</div>
</div>
<div className="col-span-12 mb-2 relative lg:mb-0 lg:col-span-1">
<Location
error={errors.destination.error}
errorMessage={errors.destination.errorMessage}
defaultValue={d2dData.destination.address}
placeholder={TO}
onLocationSelect={(val) => handleValueChange(val, "destination")}
/>
</div>
<div className="col-span-12 flex flex-col lg:pb-2 lg:mb-2 pt-1.5 lg:flex-row lg:gap-3 bl-ts-block__col lg:col-span-1">
<div
className={`lg:flex-grow bl-ts-block__col mb-6 lg:mb-0 ${
showDateRange && "bl-ts-selected"
}`}
onClick={() => {
dateRangeToggle(!showDateRange);
}}
>
<DateInput
label={"Departure Date"}
value={changeDateFormat(
d2dData.date,
DATE_FORMAT.YYYY_MM_DD,
DATE_FORMAT.DAY_MM_DATE
)}
/>
</div>
</div>
<div className="col-span-12 flex flex-col lg:flex-row lg:gap-3 bl-ts-block__col lg:col-span-1">
<TimePicker
value={d2dData.time}
onChangeHandler={(counter, value, timePeriod) =>
handleTimeChange(counter, value, timePeriod, "time")
}
onTimeInputChange={handleTimeInputChange}
/>
</div>
<div className="col-span-12 my-6 lg:my-0 lg:flex-row lg:gap-3 bl-ts-block__col lg:col-span-1">
<PassengerDropDown
label={"Passengers"}
onUpdate={handlePassengerCount}
passengerOptions={Object.entries(d2dPassengers.passengers)}
serviceOptions={Object.entries(d2dPassengers.serviceRequests)}
classname="h-12 mt-1.5"
selected={
"" +
parseInt(
d2dData.adults_count +
d2dData.kids_count +
d2dData.infants_count
)
}
totalCount={
d2dData.adults_count + d2dData.kids_count + d2dData.infants_count
}
/>
</div>
{isPlusDetailPage && <SearchBtn loading={loading} />}
</div>
{!isPlusDetailPage && <SearchBtn loading={loading} />}
<DateComponent
showDateRange={showDateRange}
dateValue={dateValue}
handleDateChange={handleDateChange}
dateType={"single"}
label={trainSearchWidget.searchType.label}
dateRangeToggle={dateRangeToggle}
classname={`${dateCompClass} ${isPlusDetailPage ? "top-36" : "top-28"}`}
handleDateSelectionComplete={dateRangeToggle}
/>
</>
);
};
export default Door2DoorService;