0

I have a google-map with customized markers. Those markers are logos of companies. After inquiring the APIs I am able to obtain a json file with the vessels I am interested in.

The problem I have is that I have been trying to inject these vessels into a table on the user interface, without success unfortunately. How to do that?

map

Below the typical response from the API

[  
    {  
        "AIS":{  
            "MMSI":227441980,
            "TIMESTAMP":"2017-08-11 11:17:37 UTC",
            "LATITUDE":46.1459,
            "LONGITUDE":-1.16631,
            "COURSE":360.0,
            "SPEED":0.0,
            "HEADING":511,
            "NAVSTAT":1,            
            "IMO":0,
            "NAME":"CLEMENTINE",
            "CALLSIGN":"FJVK",
            "TYPE":60,
            "A":0,
            "B":0,
            "C":0,
            "D":0,
            "DRAUGHT":0.0,
            "DESTINATION":"",
            "ETA_AIS":"00-00 00:00",
            "ETA":"",
            "SRC":"TER",
            "ZONE": "North Sea",
            "ECA": true      
        }
    }
]

Below the code I am using to inject the value from the API fetch into the Table:

ShipTracker.js

import React from 'react';
import { Table } from 'reactstrap';

const shipCompanyMap = {
    MICHIGAN: 'DONJON',
    ATLANTIC SALVOR': 'DONJON',
    STUYVESANT: 'DUTRA'
};

const Ship = ({ ship, logoMap, logoClick }) => {
const shipName = ship.AIS.NAME;
const company = shipCompanyMap[shipName];
const img = logoMap[company && company.split(' ').join('').toUpperCase()];
return (
    <div onClick={(event) => logoClick(event, ship)}>
        {/* Render shipImage image */}
        <img src={img} alt="Logo" />
    </div>
);
};
export { Ship };

const ShipTracker = ({ ships, setActiveShip }) => {
console.log('These are the ships: ', { ships });

return (
    <div className="ship-tracker">
        <Table className="flags-table" responsive hover>
            <thead>
                <tr>
                    <th>#</th>
                    <th>MMSI</th>
                    <th>TIMESTAMP</th>
                    <th>LATITUDE</th>
                    <th>LONGITUDE</th>
                    <th>COURSE</th>
                    <th>SPEED</th>
                    <th>HEADING</th>
                    <th>NAVSTAT</th>
                    <th>IMO</th>
                    <th>NAME</th>
                    <th>CALLSIGN</th>
                </tr>
            </thead>
            <tbody>
                {ships.map((ship, index) => {
                    // const { IMO, NAME, CALLSIGN, HEADING, SOG, MMSI, LONGITUDE, LATITUDE } = ship;
                    // const cells = [ NAME, CALLSIGN, HEADING, SOG, IMO, MMSI, LONGITUDE, LATITUDE ];

                    const {
                        MMSI,
                        TIMESTAMP,
                        LATITUDE,
                        LONGITUDE,
                        COURSE,
                        SPEED,
                        HEADING,
                        NAVSTAT,
                        IMO,
                        NAME,
                        CALLSIGN
                    } = ship;

                    const cells = [
                        MMSI,
                        TIMESTAMP,
                        LATITUDE,
                        LONGITUDE,
                        COURSE,
                        SPEED,
                        HEADING,
                        NAVSTAT,
                        IMO,
                        NAME,
                        CALLSIGN
                    ];

                    return (
                        <tr
                            onClick={() => setActiveShip(ship.AIS.NAME, ship.AIS.LATITUDE, ship.AIS.LONGITUDE)}
                            key={index}
                        >
                            <th scope="row">{index}</th>
                            {cells.map((cell) => <td key={ship.AIS.MMSI}>{cell}</td>)}
                        </tr>
                    );
                })}
            </tbody>
        </Table>
    </div>
);
};

export default ShipTracker;

The file GoogleMap.js below is carrying <ShipTracker /> information:

class BoatMap extends Component {
    constructor(props) {
        super(props);
        this.state = {
            buttonEnabled: false,
            buttonClickedAt: new Date(),
            progress: 0,
            ships: [],
            type: 'All',
            shipTypes: [],
            activeShipTypes: [],
            logoMap: {}
        };
        this.updateRequest = this.updateRequest.bind(this);
        this.countDownInterval = null;
    }

    async componentDidMount() {
        this.countDownInterval = setInterval(() => {
        }, 500);

        await this.updateRequest();

        const shipTypeResults = await Client.getEntries({
            content_type: 'comp'
        });
        const shipTypes = shipTypeResults.items.map((data) => data.fields);

        const logoMap = shipTypes.reduce((acc, type) => {
            return {
                ...acc,
                [type.name]: type.images.fields.file.url
            };
        }, {});
        this.setState({
            logoMap
        });
    }

    componentDidUpdate(prevProps, prevState) {
        if (this.state.type !== prevState.type) {
            console.log('dropdown value changed for ' + this.state.type);
        }
    }

    async updateRequest() {
        const url = 'http://localhost:3001/hello';
        const fetchingData = await fetch(url);
        const ships = await fetchingData.json();

        this.setState({
            ships
        });
    }

    handleMarkerClick = (event, data) => {
        this.props.setActiveShip(data.AIS.NAME, data.AIS.LATITUDE, data.AIS.LONGITUDE);
    };

    render() {
        console.log('ships ', this.state.ships);
        return (
            <div className="google-map">
                <GoogleMapReact
                    bootstrapURLKeys={{ key: 'KEY' }}
                    center={{
                        lat: this.props.activeShip ? this.props.activeShip.latitude : 37.99,
                        lng: this.props.activeShip ? this.props.activeShip.longitude : -97.31
                    }}
                    zoom={5.5}
                >
                    {/* Rendering all the markers here */}
                    {this.state.ships.map((ship) => (
                        <Ship
                            ship={ship}
                            key={ship.AIS.MMSI}
                            lat={ship.AIS.LATITUDE}
                            lng={ship.AIS.LONGITUDE}
                            logoMap={this.state.logoMap}
                            logoClick={this.handleMarkerClick}
                        />
                    ))}
                </GoogleMapReact>
            </div>
        );
    }
}


export default class GoogleMap extends React.Component {
    state = {
        ships: [],
        activeShipTypes: [],
        activeCompanies: [],
        activeShip: null
    };

    setActiveShip = (name, latitude, longitude) => {
        this.setState({
            activeShip: {
                name,
                latitude,
                longitude
            }
        });
    };

    render() {
        return (
            <MapContainer>

                <BoatMap
                    setActiveShip={this.setActiveShip}
                    activeShip={this.state.activeShip}
                    handleDropdownChange={this.handleDropdownChange}
                />
                <ShipTracker
                    ships={this.state.ships}
                    setActiveShip={this.setActiveShip}
                    onMarkerClick={this.handleMarkerClick}
                />
            </MapContainer>
        );
    }
}

I have been researching a lot and came across this source and this other source which were useful but didn't solve the problem. Am I maybe misunderstanding the response of the API and how to inject the data?

Thanks for pointing in the right direction for solving this issue.

1 Answer 1

1

You just need to go one level deeper on your destructuring:

If you log ship, it will be an object looking like this {AIS: {...}}. So, change this: const {MMSI, ... } = ship to const {MMSI, ... } = ship.AIS.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for reading the question. I put your modification but it does not work. The console.log('These are the ships: ', { ships }); in the ShipTracker.js still gives an empty array and I really have no idea why. I can confirm that the fetch from the API is successful though. I get all the ships I would like to display on the table.
I also noticed that GoogleMap.js has ships in its state but it never gets set to anything. The actual source of data is in BoatMap's state.ships. I was passing that down from BoatMap.js to a prop to GoogleMap.js and remove the state.ships from GoogleMap.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.