0% found this document useful (0 votes)
8 views5 pages

Image Problem

Uploaded by

hspandit071
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views5 pages

Image Problem

Uploaded by

hspandit071
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

### 1. **Models/Listing.

js**
No change is needed here, as the model seems fine for handling the image URL. But
I'll make sure the `image.url` is always passed correctly.

```javascript
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Review = require("./review.js");

const listingSchema = new Schema({


title: {
type: String,
required: true,
},
description: {
type: String,
},
image: {
url: {
type: String,
default: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-
736885_1280.jpg",
},
},
price: {
type: Number,
},
location: {
type: String,
},
country: {
type: String,
},
reviews: [
{
type: Schema.Types.ObjectId,
ref: "Review",
},
],
});

listingSchema.post("findOneAndDelete", async (listing) => {


if (listing) {
await Review.deleteMany({ _id: { $in: listing.reviews } });
}
});

const Listing = mongoose.model("Listing", listingSchema);


module.exports = Listing;
```

### 2. **Edit.ejs**
Make sure that the `image.url` field is correctly populated when editing. In your
form, you are handling the image URL input correctly. However, let's ensure that
the field is updated after editing.

```ejs
<%= layout("/layouts/boilerplate") %>
<div class="row mt-3">
<div class="col-8 offset-2">
<h3>Edit your Listing</h3>
<form method="POST" action="/listings/<%= listing._id %>?_method=PUT"
noValidate class="needs-validation">
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input name="listing[title]" value="<%= listing.title %>" type="text"
class="form-control" required>
<div class="valid-feedback">Title looks good</div>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea name="listing[description]" class="form-control" required><%=
listing.description %></textarea>
<div class="invalid-feedback">Please enter a short description</div>
</div>
<div class="mb-3">
<label for="image" class="form-label">Image URL</label>
<input name="listing[image][url]" value="<%= listing.image.url %>"
type="text" class="form-control" required>
<div class="invalid-feedback">Please enter a valid link</div>
</div>
<div class="row">
<div class="mb-3 col-md-4">
<label for="price" class="form-label">Price</label>
<input name="listing[price]" value="<%= listing.price %>"
type="number" class="form-control" required>
<div class="invalid-feedback">Price should be valid</div>
</div>
<div class="mb-3 col-md-8">
<label for="country" class="form-label">Country</label>
<input name="listing[country]" value="<%= listing.country %>"
type="text" class="form-control" required>
<div class="invalid-feedback">Country name should be valid</div>
</div>
</div>
<div class="mb-3">
<label for="location" class="form-label">Location</label>
<input name="listing[location]" value="<%= listing.location %>"
type="text" class="form-control" required>
<div class="invalid-feedback">Location should be valid</div>
</div>
<button class="btn btn-dark edit-btn mt-3">Edit</button>
</form>
</div>
</div>
```

### 3. **Show.ejs**
Ensure the image is displayed by properly accessing the `image.url` in the `img`
tag. The rest of your code for the show page looks good.

```ejs
<%= layout("/layouts/boilerplate") %>
<div class="row">
<div class="col-8 offset-3 mt-3">
<h3><%= listing.title %></h3>
</div>
<div class="card col-6 offset-3 show-card listing-card">
<img src="<%= listing.image.url %>" class="card-img-top show-img"
alt="listing_image">
<div class="card-body">
<p class="card-text">
<%= listing.description %><br>
&#8377; <%= listing.price.toLocaleString("en-IN") %><br>
<%= listing.location %><br>
<%= listing.country %>
</p>
</div>
</div>
<br>
<div class="btns">
<a href="/listings/<%= listing._id %>/edit" class="btn btn-dark col-1
offset-3 edit-btn">Edit</a>

<form method="POST" action="/listings/<%= listing._id %>?_method=DELETE">


<button class="btn btn-dark offset-5">Delete</button>
</form>
</div>

<div class="col-8 offset-3 mb-3">


<hr>
<h4>Leave a Review</h4>
<form action="/listings/<%= listing.id %>/reviews" method="POST" novalidate
class="needs-validation">
<div class="mb-3 mt-3">
<label for="rating" class="form-label">Rating</label>
<input type="range" min="1" max="5" id="rating"
name="review[rating]" class="form-range">
</div>
<div class="mb-3 mt-3">
<label for="comment" class="form-label">Comments</label>
<textarea name="review[comment]" id="comment" col="30" rows="5"
class="form-control" required></textarea>
<div class="invalid-feedback">Please add some comments for
review</div>
</div>
<button class="btn btn-outline-dark">Submit</button>
</form>

<hr>

<p><b>All Reviews</b></p>
<div class="row">

<% for(review of listing.reviews) { %>


<div class="card col-5 ms-3 mb-3">
<div class="card-body">
<h5 class="card-title">Jane Doe</h5>
<p class="card-text"><%= review.comment %></p>
<p class="card-text"><%= review.rating %> Stars</p>
</div>
<form class="mb-3" method="POST" action="/listings/<%= listing._id
%>/reviews/<%= review._id %>?_method=DELETE">
<button class="btn btn-sm btn-dark">Delete</button>
</form>
</div>
<% } %>
</div>
</div>
</div>
```

### 4. **Routes.js**
No changes are needed for the routes. The current route handling for `GET`, `POST`,
and `PUT` for listings should work fine. The image URL is updated in the database
when the form is submitted.

```javascript
const express = require("express");
const router = express.Router();
const wrapAsync = require("../utils/wrapAsync.js");
const ExpressError = require("../utils/ExpressError.js");
const { listingSchema, reviewSchema} = require("../schema.js");
const Listing = require("../models/listing.js");

const validateListing = ((req, res, next) => {


let {error} = listingSchema.validate(req.body);
if(error) {
let errMsg = error.details.map((el) => el.message).join(",");
throw new ExpressError(400, errMsg);
} else {
next();
}
});

// Index Route
router.get("/", wrapAsync(async (req, res) => {
const allListings = await Listing.find({});
res.render("listings/index.ejs", { allListings });
}));

// New Route
router.get("/new", (req, res) => {
res.render("listings/new.ejs");
});

// Show Route
router.get("/:id", wrapAsync(async (req, res) => {
let {id} = req.params;
const listing = await Listing.findById(id).populate("reviews");
res.render("listings/show.ejs", { listing });
}));

// Create Route
router.post("/", validateListing, wrapAsync(async (req, res, next) => {
const newListing = new Listing(req.body.listing);
await newListing.save();
res.redirect("/listings");
}));

// Edit Route
router.get("/:id/edit", wrapAsync(async (req, res) => {
let {id} = req.params;
const listing = await Listing.findById(id);
res.render("listings/edit.ejs", { listing });
}));

// Update Route
router.put("/:id", validateListing, wrapAsync(async (req, res) => {
let {id} = req.params;
await Listing.findByIdAndUpdate(id, { ...req.body.listing });
res.redirect(`/listings/${id}`);
}));

// Delete Route
router.delete("/:id", wrapAsync(async (req, res) => {
let {id} = req.params;
let deletedListing = await Listing.findByIdAndDelete(id);
console.log(deletedListing);
res.redirect("/listings");
}));

module.exports = router;
```

You might also like