Hej. I want to create a react admin input component MapInput where I'm given a map with drawing controls github. There I'm able to draw my polygon and get GeoJSON as a result, which I can then send to my backend REST API server (json-server).
My system consists of my react client program, and a json-server with REST API. Example for an area in my REST API:
{
"id": "4",
"name": "Area 4",
"description": "This is area 4.",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-1.8017578124999998, 52.45600939264076],
[0.406494140625, 52.20760667286523],
[0.560302734375, 53.48804553605622],
[-1.8017578124999998, 52.45600939264076]
]
]
}
}
At the moment, with my MapInput tag, I can draw a polygon and I can log the GeoJSON, but I can't figure out how to pass it to the react admin dataProvider, for it to be able to send it to my server.
I follow this instructions.
Inside my components/CreateMyArea.tsx component (POST)
import React from 'react';
import { Create, SimpleForm, TextInput } from 'react-admin';
import { MapInput } from '../components/MapboxGl';
export const CreateMyArea = (props: any) => {
return (
<Create title="Create my area" {...props}>
<SimpleForm>
<TextInput label="Name" source="name" />
<TextInput multiline label="Description" source="description" />
<MapInput />
</SimpleForm>
</Create>
);
};
In MapInput tag, how can I pass the "geometry" parameter as I do with "name" and "description" (JSON example) in source tag?
Inside my components/MapboxGl.tsx component
import * as React from 'react';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
import ReactMapboxGl from 'react-mapbox-gl';
import DrawControl from 'react-mapbox-gl-draw';
const Map = ReactMapboxGl({
accessToken:
'ACCESS-TOKEN'
});
//...
export const MapInput = () => {
return (
<Map
style="mapbox://styles/mapbox/streets-v11"
containerStyle={{
height: '400px',
width: '800px'
}}
>
<DrawControl
displayControlsDefault={false}
controls={{
trash: true,
polygon: true
}}
//onDrawCreate={onDrawCreate} // with this method I can console.log created geoJson
//onDrawUpdate={onDrawUpdate}
/>
</Map>
);
};
Your custom input component must display and allow the change of the polygon. This data is in the form state, handled by react-final-form. So you'll need to use react-final-form's useField()
hook to grab the input value and change callback:
import { useField } from 'react-final-form';
export const MapInput = () => {
const { input, meta } = useField('geometry');
const { value, onChange } = input;
// do what you want with value and onChange
In this example, I didn't make the field name ('geometry') customizable. If you want to reuse the same input component for a different source, add support for a source
prop - just like for react-admin Input components:
export const MapInput = ({ source }) => {
const { input, meta } = useField(source);
const { value, onChange } = input;
// do what you want with value and onChange
You can learn more about writing your own input components in the react-admin documentation:
https://marmelab.com/react-admin/Inputs.html#writing-your-own-input-component