React/Redux newbie here. I have a form input that allows a user to enter a doctor issue. It returns a list of doctors from the server via Redux action, and displays the doctor list and a marker for each doctor's location on the map (react-google-maps).
When I click submit, the list of doctors for the correct issue displays, the map is there, but with no markers. I can get the markers on the map to display ONLY after submitting the form, THEN clicking on a doctor from the list to display their details.
Want: Enter a doctor issue and render both the list of doctors and markers on the map when the user clicks submit. Then, select a doctor to see their details page (that's another question, routing to dynamic a detail page).
I think, I need to use a life-cycle method but not sure how to implement it. Or, is there a better way to handle this with Redux?
Doctor component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import DoctorSearchForm from '../../containers/doctors/DoctorSearchForm';
import DoctorList from './DoctorList';
import Map from '../maps/Map';
class Doctors extends Component {
constructor(props) {
super(props);
this.state = {
markers: [],
isMarkerShown: false
}
}
componentDidMount() {
this.getMarkers();
}
getMarkers = () => {
let practices = this.props.doctors.map(function(doctor, index) {
return {
title: doctor.profile.first_name + ' ' + doctor.profile.last_name,
location: {
lat: doctor.practices[0].visit_address.lat,
lng: doctor.practices[0].visit_address.lon
}
}
});
this.setState({ markers: practices, isMarkerShown: true });
}
render() {
const { doctors, match } = this.props;
return (
<div>
<DoctorSearchForm getMarkers={this.getMarkers} />
<div className="row">
<div className="col-md-4">
<DoctorList doctors={doctors} match={match} />
</div>
<div className="col-md-8">
<Map
isMarkerShown={this.state.isMarkerShown}
center={{ lat: 45.6318,lng: -122.6716 }}
zoom={12}
markers={this.state.markers}
/>
</div>
</div>
</div>
);
}
}
Doctors.propTypes = {
doctors: PropTypes.array.isRequired,
match: PropTypes.object.isRequired
}
export default Doctors;
DoctorList component:
import React from "react";
import { Route } from 'react-router-dom';
import DoctorItem from './DoctorItem';
import DoctorView from './DoctorView';
class DoctorList extends React.Component {
render() {
const { doctors, match } = this.props;
const linkList = doctors.map((doctor, index) => {
return (
<DoctorItem doctor={doctor} match={match} key={index} />
);
});
return (
<div>
<h3>DoctorList</h3>
<ul>{linkList}</ul>
<Route path={`${match.url}/:name`}
render={ (props) => <DoctorView data= {this.props.doctors} {...props} />}
/>
</div>
);
}
}
export default DoctorList;
DoctorItem component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link, Route } from 'react-router-dom';
import DoctorView from './DoctorView';
const DoctorItem = (props) => {
const { doctor, match } = props;
return (
<li>
<Link to={{ pathname: `${match.url}/${doctor.profile.first_name}-${doctor.profile.last_name}` }}>
{doctor.profile.first_name} {doctor.profile.last_name}
</Link>
</li>
)
}
DoctorItem.propTypes = {
doctor: PropTypes.object.isRequired,
};
export default DoctorItem;
DoctorView component:
import React from 'react';
const DoctorView = ({ data, match }) => {
const doctor = data.find(p => `${p.profile.first_name}-${p.profile.last_name}` === match.params.name);
let doctorData;
if (doctor) {
const mappedSpecialties = Object.entries(doctor.specialties).map(([index, specialty]) => {
return <li key={index} id={index}>{specialty.description}</li>;
});
doctorData =
<div>
<h5><strong>{doctor.profile.first_name} {doctor.profile.last_name}</strong> - {doctor.profile.title}</h5>
<img src={doctor.profile.image_url} alt={"Dr." + doctor.profile.first_name + " " + doctor.profile.last_name} />
<ul>{mappedSpecialties}</ul>
<p>{doctor.profile.bio}</p>
</div>;
}
return (
<div>
{doctorData}
</div>
)
}
export default DoctorView;
Map component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
import { compose, withProps } from "recompose";
export default Map = compose(
withProps({
googleMapURL:
"https://maps.googleapis.com/maps/api/js?key={MY_KEY}&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withScriptjs,
withGoogleMap
)(props => (
<GoogleMap defaultZoom={9} defaultCenter={{ lat: 45.6318,lng: -122.6716 }}>
{props.markers.map((doctor, index) => {
const marker = {
position: { lat: doctor.location.lat, lng: doctor.location.lng },
title: doctor.title
}
return <Marker key={index} {...marker} />;
})}
</GoogleMap>
));
I've spent several days trying and searching for answers but no luck. Any help would be greatly appreciated!