by Ian Schoonover
Add Google Maps scripts to your application
Update new and edit forms
If you already have a google (or gmail) account, you can skip this step.
If not, then go to https://accounts.google.com/SignUp
and create one (it's free).
Sign into your google account the navigate to https://developers.google.com/maps/web/
in your browser and click "GET A KEY"
Click on "Select or create project" dropdown then click "Create a new project"
Enter a name for your project then click "CREATE AND ENABLE API"
Now copy the API key and store it somewhere so it can be used later...
Click here to copy
*Do not click FINISH yet
Click on "API Console" where it says "To improve your app's security, restrict this key's usage in the API Console."
This step is crucial for protecting your API key
*If the link from above doesn't take you to the geocoding API then search for it in the API library
*If the link from above doesn't take you to the credentials page then click the key from the left-hand menu
export GEOCODER_API_KEY=your-key-here
heroku config:set GEOCODER_API_KEY=your-key-here
Open /campgrounds/show.ejs in your code editor and add the following scripts to the bottom of the view, right above where we include the footer partial:
<script>
function initMap() {
var lat = <%= campground.lat %>;
var lng = <%= campground.lng %>;
var center = {lat: lat, lng: lng };
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 8,
center: center,
scrollwheel: false
});
var contentString = `
<strong><%= campground.name %><br />
<%= campground.location %></strong>
<p><%= campground.description %></p>
`
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: center,
map: map
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=API-KEY-HERE&callback=initMap"></script>
*be sure to replace API-KEY-HERE with the first key (with restrictions) that you created earlier
Create a div with an id of map directly beneath where you have the Info 1, 2 and 3 .list-group inside of .col-md-3:
<div class="col-md-3">
<p class="lead">YelpCamp</p>
<div class="list-group">
<li class="list-group-item active">Info 1</li>
<li class="list-group-item">Info 2</li>
<li class="list-group-item">Info 3</li>
</div>
<div id="map"></div>
</div>
The JavaScript from the previous slide will select this div and use it to generate the map
Open /public/stylesheets/main.css and add the following to your stylesheet:
/* Google Maps */
#map {
height: 400px;
width: 100%;
}
var mongoose = require("mongoose");
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
location: String,
lat: Number,
lng: Number,
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}
]
});
module.exports = mongoose.model("Campground", campgroundSchema);
<div class="form-group">
<label for="location">Location</label>
<input class="form-control" type="text" name="location" id="location" placeholder="Yosemite National Park, CA">
</div>
<div class="form-group">
<label for="location">Location</label>
<input class="form-control" type="text" name="location" id="location" value="<%= campground.location %>">
</div>
*I've added a label to the location input, I suggest adding labels to the other inputs as well. You can see how I did it here.
npm i -S node-geocoder
var NodeGeocoder = require('node-geocoder');
var options = {
provider: 'google',
httpAdapter: 'https',
apiKey: process.env.GEOCODER_API_KEY,
formatter: null
};
var geocoder = NodeGeocoder(options);
//CREATE - add new campground to DB
router.post("/", middleware.isLoggedIn, function(req, res){
// get data from form and add to campgrounds array
var name = req.body.name;
var image = req.body.image;
var desc = req.body.description;
var author = {
id: req.user._id,
username: req.user.username
}
geocoder.geocode(req.body.location, function (err, data) {
if (err || !data.length) {
req.flash('error', 'Invalid address');
return res.redirect('back');
}
var lat = data[0].latitude;
var lng = data[0].longitude;
var location = data[0].formattedAddress;
var newCampground = {name: name, image: image, description: desc, author:author, location: location, lat: lat, lng: lng};
// Create a new campground and save to DB
Campground.create(newCampground, function(err, newlyCreated){
if(err){
console.log(err);
} else {
//redirect back to campgrounds page
console.log(newlyCreated);
res.redirect("/campgrounds");
}
});
});
});
// UPDATE CAMPGROUND ROUTE
router.put("/:id", middleware.checkCampgroundOwnership, function(req, res){
geocoder.geocode(req.body.location, function (err, data) {
if (err || !data.length) {
req.flash('error', 'Invalid address');
return res.redirect('back');
}
req.body.campground.lat = data[0].latitude;
req.body.campground.lng = data[0].longitude;
req.body.campground.location = data[0].formattedAddress;
Campground.findByIdAndUpdate(req.params.id, req.body.campground, function(err, campground){
if(err){
req.flash("error", err.message);
res.redirect("back");
} else {
req.flash("success","Successfully Updated!");
res.redirect("/campgrounds/" + campground._id);
}
});
});
});
Congratulations! Your YelpCamp app now has a Google Maps location feature
If you have any questions then please create a thread in the Q&A
You can find the source code for this tutorial in the google-maps directory of my c9 workspace