I have a Google map in my react application which allows users to sign up (by entering their name). It then gets their location every 1 second and sends it to all the other users currently using the app.
I am trying to plot the users on a map using google-map-react. This should update every time a user is added, or their location changes and reflect this with their marker moving on the map.
It is console logging the usersArray correctly, but users is not being updated, am I doing setState wrong?
const Map = ({ location, zoomLevel }) => {
const { name } = useParams();
const [messages, setMessages] = useState([]);
const ws = useRef();
let [latitude, setLatitude] = useState('');
let [longitude, setLongitude] = useState('');
const [isConnectionOpen, setConnectionOpen] = useState(false);
const [users, setUsers] = useState([]);
useEffect(() => {
ws.current = new WebSocket('ws://localhost:8081');
//new user has connected
ws.current.onopen = () => {
setConnectionOpen(true);
};
//sending message to other users
ws.current.onmessage = (ev) => {
const message = JSON.parse(ev.data);
//update users function
handleAddNewUser(message);
setMessages((_messages) => [..._messages, message]);
};
return () => {};
}, []);
//checks if a message has been received my a new user. If existing user - update location
function handleAddNewUser(message) {
let usersArray = [];
let newUser = true;
if (users.length == 0) {
usersArray.push(message);
} else {
for (let user of users) {
if (message.sender == user.sender) {
newUser = false;
user = message;
}
}
if (newUser == true) {
usersArray.push(message);
}
}
console.log(usersArray);
// update the state to the updatedUsers
setUsers(usersArray);
console.log(users);
}
//triggers the send function every 1 second
useEffect(() => {
const interval = setInterval(() => {
send();
}, 1000);
return () => clearInterval(interval);
}, []);
//sends the users location as a message to all the other users
const send = () => {
if (navigator.geolocation) {
navigator.geolocation.watchPosition(function (position) {
latitude = position.coords.latitude.toString();
longitude = position.coords.longitude.toString();
ws.current.send(JSON.stringify({ sender: name, latitude: latitude, longitude: longitude }));
setLatitude('');
setLongitude('');
});
}
};
return (
<div className='map'>
<div className='google-map'>
<GoogleMapReact
bootstrapURLKeys={{ key: 'keyID' }}
defaultCenter={location}
defaultZoom={zoomLevel}>
users.map(user => {
<MyGreatPlace lat={user.latitude}
lng={user.longitude} text=
{user.sender} />
})
</GoogleMapReact>
</div>
</div>
);
};
export default Map;
Also, when plotting the users on the map, i am getting this error: Unexpected token. Did you mean {'>'} or >?
CodePudding user response:
You should check if user exist first. Like this:
if(users){ setUsers(userArray) }
CodePudding user response:
Try logging users in useEffect
with users in the dependency array.
//triggers the send function every 1 second
useEffect(() => {
console.log(users)
const interval = setInterval(() => {
send();
}, 1000);
return () => clearInterval(interval);
}, [users]);
And to render map you usually do it like that:
{
users.map((user, i) => <li>user</li>)
}