Connecting Redux Store to Component to populate map with markers

Viewed 261

In short I'm trying to learn how to use redux. As the title suggests I'm trying to connect the redux store to the component so that it can populate the map with markers (that I've fetched on a server).

I know I have connected it when I load componentWillMount(). But by doing so it returns an array of objects, which is not what I exactly want.

I don't know if I'm saying this correctly, but how do I make it so that it returns a state / props that I can use in my ./Component to populate markers on a map?

[EDIT1: I've included changes as suggested Pritish]

Thanks in advance.

./Screen

class FindOnMapScreen extends Component {

  constructor(props) {
    super(props);
    this.state = {
      userLocation: null,
      plots: []
    };
  }

  getUserLocationHandler = () => {
    navigator.geolocation.getCurrentPosition(position => {
      this.setState({
        userLocation: {
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          latitudeDelta: 0.0622,
          longitudeDelta: 0.0421,
        }
      });
    }, err => console.log(err));
  };

componentDidMount() {
  this.props.onLoadPlacesToMap();
}

  render() {
    console.warn("props", this.props)
    return  (
      <View style={styles.container}>
        <FetchLocation onGetLocation={this.getUserLocationHandler} />
        <UsersMap 
          userLocation={this.state.userLocation}
          props={this.props.plots}
        />
      </View>
      )
    }
  };


const mapStateToProps = state => {
  return {
    plots: state.mapPlaces.plots
  };
};

const mapDispatchToProps = dispatch => {
  return {
      onLoadPlacesToMap: () => dispatch(getPlacesOnMap())
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(FindOnMapScreen);

./Component

const usersMap = props => {
let userLocationMarker = null;

if (props.userLocation) {
    userLocationMarker = <MapView.Marker coordinate={props.userLocation} />;
}

const plots = props.plots.map(plots => //.. tried to access here
    <MapView.Marker 
        coordinate={plots} 
        key={plots.id}
    />
);

return (
    <View style={styles.mapContainer}>
        <MapView 
            initialRegion={{
                latitude: 37.78825,
                longitude: -122.4324,
                latitudeDelta: 0.0622,
                longitudeDelta: 0.0421,
            }}
            region={props.userLocation}
            style={styles.map}
        >
            {userLocationMarker}
        </MapView>
    </View>
  );
};

./Store/Actions

export const getPlacesOnMap = () => {
return dispatch => {
    dispatch(authGetToken())
        .then(token => {
            return fetch("myAppURL/file.json?auth=" + token);
        })
        .catch(() => {
            alert("No valid token found!");
        })
        .then(res => {
            if (res.ok) {
                return res.json();
            } else {
                throw(new Error());
            }
        })
        .then(parsedRes => {
            const plots = [];
            for (let key in parsedRes) {
                plots.push({
                    latitude: parsedRes[key].location.latitude,
                    longitude: parsedRes[key].location.longitude,
                    id: key
                  });
                } console.log(plots)
                dispatch(mapPlaces(plots));
              })
        .catch(err => {
            alert("Oops! Something went wrong, sorry! :/");
            console.log(err);
        });
    };
};

export const mapPlaces = plots => {
    return {
        type: MAP_PLACES,
        plots: plots
    };
};

./Store/Reducer

const initialState ={
    plots: []
};

const reducer = (state = initialState, action) => {
    switch (action.type) {
      case MAP_PLACES:
        return {
            ...state,
            places: action.plots
        };
        default:
            return state;
    }
};

./ConfigureStore

const rootReducer = combineReducers({
    mapPlaces: mapPlacesReducer
});
1 Answers

Since your Component is a stateless one, you can pass the plot props to it directly from this.props which is bound to the state of the store using mapStateToProps.

componentDidMount {
  this.props.onLoadPlacesToMap() // ... Call your prop bound dispatcher func here
}

<UsersMap 
   userLocation={this.state.userLocation} 
   plots={this.props.plots}
/>

and in your Component , you can access them by props.plots

In your reducer , you need to either change places to plots or map and map them similarly in your parent class.

case MAP_PLACES:
   return {
     ...state,
     plots: action.plots
 };
Related