I am developing a web app that finds the nearest users (neighbors) and display their product that they want to buy, they also have the ability to sell.
the app uses node.js, javaScript, mongodb, mongoose.
my problem is with sorting the products. I want to display the products sorted from the nearest users of the loggedIn user to the furthest users but I could not do that. I have spent hours but I just could not figure out what is wrong
const Product = require('../models/products')
const User = require('../models/user')
module.exports.index = async (req, res) => {
try {
// get logged in user location
const currentUserLocation = req.user.location.coordinates;
// sorting users
const nearbyUsers = await User.find({
location: {
$near: {
$geometry: {
type: 'Point',
coordinates: currentUserLocation
},
}
}
});
// Get products of nearby users
const products = await Product.find({ author: { $in: nearbyUsers.map(user => user._id) } });
console.log("this is the users log: ",nearbyUsers)
console.log('this is the products log: ',products)
// Render the products on the main page
res.render('products/index', { products });
} catch (error) {
console.error('Error fetching nearby products:', error);
res.status(500).send('Internal Server Error');
}
};
user model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const passportLocalMongoose = require('passport-local-mongoose');
const Product = require("../models/products")
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
phoneNumber: Number,
location: {
type: {
type: String,
enum: ['Point'],
required:true
},
coordinates: {
type: [Number],
required:true
}
}})
UserSchema.index({ location: '2dsphere' });
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', UserSchema);
product model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const productSchema = new Schema ({
title:String,
images:[
{
url:String,
filename:String
}
],
price:Number,
description:String,
author:{
type: Schema.Types.ObjectId,
ref:'User'
},
transactionType: {
type: String,
enum: ['sell', 'rent'],
},
status: {
type: String,
enum: ['available', 'sold', 'pending'],
default: 'available' // Default status is available
},
});
module.exports=mongoose.model('Products',productSchema)
the index ejs file
<%- layout ('/layouts/boilerplate') %>
<h1>all products</h1>
<div>
<a href="/products/new">add a product</a>
<a href="/products/borrowing-requests">View Borrowing Requests</a>
</div>
<% for(let product of products) {%>
<div class="card" mb-3>
<div class="row">
<div class="col-md-4">
<img src="<%= product.images[0].url %>" class="img-fluid" alt="Product Image"> </div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title"><%= product.title %></h5>
<p class="card-text"><%= product.price %></p>
<p class="card-text">
<small class="text-secondary"><%= product.description %></small>
</p>
<a class="btn btn-primary" href="/products/<%= product._id %>">view <%= product.title %> </a>
</div>
</div>
</div>
</div>
</div>
<% } %>
I think that there Is something wrong with the logic of the code here but I can’t figure It out, I have provided the code relevant to the problem.
do you think that there Is a better way to do this job?, do I need to use something like using mapbox for the code?
If you have any suggestions, please let me know
Note: The coordinates of users are already in the database