Uncaught TypeError: Cannot read properties of undefined (reading 'coordinates') for mapbox

Viewed 835

I keep getting a typeError when using mapbox and trying to do user inputted coordinates for the marker and center.

This is the error:

`showPageMap.js:5 Uncaught TypeError: Cannot read properties of undefined (reading 'coordinates')
    at showPageMap.js:5
(anonymous) @ showPageMap.js:5`

My controller looks like this:

`const Adventure = require('../models/listings');
const mbxGeocoding = require("@mapbox/mapbox-sdk/services/geocoding");
const mapBoxToken = process.env.MAPBOX_TOKEN;
const MapboxClient = require('@mapbox/mapbox-sdk');
const geocoder = mbxGeocoding({ accessToken: mapBoxToken });
const { cloudinary } = require('../cloudinary');
const mapboxgl = require('mapbox-gl');


module.exports.index = async (req, res) => {
    const adventures = await Adventure.find({});
    res.render('adventures', { adventures })
};

module.exports.renderNewForm = (req, res) => {
    res.render('adventures/new')
};

module.exports.createAdventure = async (req, res, next) => {
    const geoData = await geocoder.forwardGeocode({
        query: req.body.adventure.location,
        limit: 1
    }).send()
    const adventure = new Adventure(req.body.adventure);
    adventure.geometry = geoData.body.features[0].geometry;
    adventure.images = req.files.map(f => ({ url: f.path, filename: f.filename}));
    adventure.author = req.user._id;
    console.log(adventure);
    await adventure.save();
    req.flash('success', 'Successfully made adventure');
    res.redirect(`/adventures/${adventure._id}`)
};

module.exports.showAdventure = async (req, res) => {
    const adventure = await Adventure.findById(req.params.id).populate({
        path: 'reviews',
        populate: {
            path:'author'
        }
    }).populate('author');
    if (!adventure) {
        req.flash('error', 'Cannot find that campground!');
        return  res.redirect('/adventures');
    }
    res.render('show', { adventure })
};`

My model looks like this:

`const { number } = require('joi');
const mongoose = require('mongoose');
const { adventureSchema } = require('../schemas');
const review = require('./review');
const Schema = mongoose.Schema;

const ImageSchema = new Schema({
    url: String,
    filename: String
});

ImageSchema.virtual('thumbnail').get(function () {
    return this.url.replace('/upload', '/upload/w_200');
});

const opts = { toJSON: { virtuals: true } };

const adventuresSchema = new Schema({
    title: String,
    images: [ImageSchema],
    geometry: {
        type: {
            type: String,
            enum: ['Point'],
            required: true
        },
        coordinates: {
            type: [Number],
            required: true
        }
        
        
    },
    price: Number,
    description: String,
    location: String,
    author: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    reviews: [
        {
            type: Schema.Types.ObjectId,
            ref: 'Review'
        }
    ]
}, opts);


adventuresSchema.post('findOneAndDelete', async function (doc) {
    if(doc){
        await review.remove({
            _id: {
                $in: doc.reviews
            }
        })
    }
});



module.exports = mongoose.model('Adventure', adventuresSchema);
`
The js for the map is: `mapboxgl.accessToken = mapToken;
const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v10', // stylesheet location
    center: adventure.geometry.coordinates, // starting position [lng, lat]
    zoom: 10 // starting zoom
});

map.addControl(new mapboxgl.NavigationControl());


new mapboxgl.Marker()
    .setLngLat(adventure.geometry.coordinates)
    .setPopup(
        new mapboxgl.Popup({ offset: 25 })
            .setHTML(
                `<h3>${adventure.title}</h3><p>${adventure.location}</p>`
            )
    )
    .addTo(map)`

The code uses mongoose, mongodb, and express.

I have tried most solutions on this and none seem to work for me. I redid the model and everything and it simply won't take coordinates which mapbox docs tell me is allowed and included in the api req.

I've been stuck for many hours and nothing works, please help

1 Answers

I realize this is an old question but I wanted to answer just to have it recorded online for people to find easily.

The script at the bottom of your Views Index page and Show should show this -

// Views Show Page EJS
<script>
    const mapToken = '<%- process.env.MAPBOX_TOKEN %>';
    let campground = '<%- JSON.stringify(campground) %>';
    campground = JSON.parse(campground);
  </script>
  <script src="/javascripts/showPageMap.js"></script>
  </script>

// Views Index EJS

    <script>
      const mapToken = '<%- process.env.MAPBOX_TOKEN %>';
      let campgrounds = '<%- JSON.stringify(campgrounds) %>'
      campgrounds = { features: JSON.parse(campgrounds) }
    </script>
    <script src="/javascripts/clusterMap.js"></script>

Also, please remove any seeding that have an apostrophe in the name of the city. In the bootcamp I finished a city "O'Fallon" was throwing off my parsing and I had to remove it from the list, or just delete the campsite.

I kept the structure how I have it set up on my project, but you should be able to work backwards to customize it for yourself.

Related