Adding slug to req params url in express - node.js

I'm using the 'slug' npm library to give-strings-dashes-for-url-cleanliness. The library works when I console.log() a string, and it's required properly into all of the relevant controllers.
However, I can't figure out how implement slug() properly to format my URLs. The problem I'm having is that a product name might be "Foo Bar Baz Quux", but I can't seem to find the right implementation for slug() without disrupting the connection between the app.js route and the findOne query via mongoose.
app.js
app.get('/market/:product_name', marketController.getProduct);
controller.js
exports.getProduct = function(req, res, next) {
var product_name = req.params.product_name;
// var slugProduct = slug(product_name);
Product.findOne({'name': product_name}, function(err, product) {
if (err) return next(err);
return res.send(product.data);
});
}

Perhaps you could "slugify" a product by defining a slug property while setting up your "Product Schema". I can confirm it works if using mongoose with along mongoose-slug-generator plugin, see link... You could set it up as follows:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const slug = require('mongoose-slug-generator');
// * mongoose slug generator options
const options = {
separator: '-',
lang: 'en',
truncate: 120
};
// * Init mongoose slug generator plugin
mongoose.plugin(slug, options);
const ProductSchema = new Schema({
name: {
type: String,
trim: true
},
slug: {
type: String,
slug: 'name', // genarating slug from multiple properties is allowed ['name', 'brand']
unique: true
},
price: {
type: Number,
required: true
},
brand: {
type: String,
default: 'Apple'
}
});
module.exports = mongoose.model('Product', ProductSchema);
exports.getProduct = function(req, res, next) {
const { product_name } = req.params;
Product.findOne({ slug: product_name }, function(err, product) {
if (err) return next(err);
if (!product) {
return res.status(404).json({
message: 'Product data not found.'
);
}
res.status(200).send(product);
});
}
app.get('/market/:product_name', marketController.getProduct)
// request
const response = await axios.get('/api/market/my-awesome-product')
// response.data
{
"_id": "60fh4d37ac1a1c6f58d6a5f4",
"name": "My Awesome Product",
"slug": "my-awesome-product",
"price": 85.9,
"brand": "Apple"
}

Related

ObjectParameterError: Parameter "filter" to find() must be an object, got search

this get route is giving no error in post-man but doing the same with frontend giving error in node console:
ObjectParameterError: Parameter "filter" to find() must be an object, got search
although response are fetched.
get controller
const Recent = require("../models/recent");
const getRecentByName = async (req, res, next) => {
const name = req.params.name;
let regex = new RegExp(name, "i");
let players;
try {
players = await Recent.find({ name: { $regex: regex } });
} catch (err) {
return next(err);
}
if (!players) {
return next("no player found");
}
// console.log(players);
res.json({ players });
};
exports.getRecentByName = getRecentByName;
fetching from frontend:
const searchRecords = async () => {
const data = await sendRequest(
"http://localhost:5000/api/player/recent/search/" + search,
"GET"
);
setRecord(data.players);
};
Recent:(mongoose Schema):
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const recentSchema = new Schema({
name: { type: String, required: true },
recent: [
{
team1: { type: String },
team2: { type: String },
points: { type: Number, required: true },
date: { type: Date },
},
],
});
module.exports = mongoose.model("Recent", recentSchema);
I think the problem is from the front and in the URL
you should use
http://localhost:5000/api/player/recent/search/${search}

Express api with mongoose PUT

I have endpoint:
router.put('/:customerId', async (req, res) => {
try {
const updatedCustomer = await Customer.updateOne(
{ _id: req.params.customerId },
req.body,
{ new: true }
);
res.send(updatedCustomer);
} catch {
res.json({ message: err });
}
});
const CustomerSchema = mongoose.Schema({
name: String,
surname: String
})
and after put request with only name value in my object still exist name and surname. I thought that my surname value will be delete. It works fine or not?
In your schema definition do the following
const CustomerSchema = mongoose.Schema({
name: String,
surname: String
},{
strict:false
})

how can i access mongodb document's array? (mongodb, nodejs)

Hi i have some problems with mongodb.
const mongoose = require('mongoose');
const companySchema = new mongoose.Schema({
name: String,
url: String,
images: Array
});
const categoriesSchema = new mongoose.Schema({
company: companySchema,
name: String
});
module.exports = mongoose.model('categories', categoriesSchema);
above of code is model
app.post('/addCompanyinfo', function (req, res){
var news = new Categories();
news.company[name]= req.body.company; <--- here!
news.save(function (err) {
if(err) {
console.error(err);
res.json({result: 0});
return;
}
res.json({result: 1})
})
})
and this is router code. and i want to access
categoriesSchema-> company (companySchema)-> name.
how can i access company schema's 'name' ??
your help will be a big lucky in future to you :)
You need to create an Object for Company to assign its properties
var news = new Categories();
var company = new Company();
news.company = company;
news.name = 'test category'
company.name = 'test company';
console.log(company);
console log
{ name: 'test category',
company: { _id: 5a61629b74f8df0bd73142ba, images: [] },
_id: 5a61629b74f8df0bd73142b9 }
{ name: 'test company', _id: 5a61629b74f8df0bd73142ba, images: [] }
You can post your data in json format and use bodyParser.json() middleware in your app.js, and your backend code can be this:
router.post('/', function(req, res, next) {
var news = new Categories(req.body); // create record directly with the json data
console.log(req.body.company.name); //just access it directly
news.save(function (err) {
if(err) {
console.error(err);
res.json({result: 0});
return;
}
res.json({result: 1});
});
});
and json format can be this:
{
"company": {
"name": "test company name",
"url": "http://test.com",
"image": []
},
"name": "test name"
}

Localized Values are not updating in Mongoose/Node.JS

This is an odd issue I have been seeing. I have a mongoose schema using mongoose-i18n-localize:
var mongoose = require('mongoose');
var mongooseI18n = require('mongoose-i18n-localize');
var Schema = mongoose.Schema;
var TestSchema = new Schema({
id: String,
active: {type: Boolean, default: false},
name: {type: String, required: true, i18n: true}
});
TestSchema.plugin(mongooseI18n, {
locales: ['en_US']
});
module.exports = mongoose.model('Test', TestSchema);
In my call I have this:
app.put('/test/:id', function(req, res) {
var query = {'id': req.params.id);
var test = req.body;
Test.findOneAndUpdate(query, test, function(err,p) {
if (err) {
handleError(res, err.message, "Failed to get information");
console.log(err);
} else {
res.json(p);
}
})
});
and I passed in this data:
http://localhost:123/test/1d
{
"active": true,
"name": { "en_US": "test" }
}
I can change active to true and false with no issue. But the name never changes when I make a change. Also I get no error just does not update. Has anyone seen this before or know how to fix this so I can do localization.
You should send the body using dot notation instead of brackets. It worked for me in this way:
{
"active": true,
"name.en_US": "test"
}

'populate' and working with parent / child models in Mongoose / MongoDB

I have a pretty simple setup where I'm trying to populate my Mongoose JSON responses with all Comments that belong to a Post
I thought that calling 'populate' on Post would return all comments related to the Post, but instead I'm getting an empty array. I just don't get what I'm doing wrong.
post.js
const mongoose = require('mongoose');
const db = require('./init');
const postSchema = new mongoose.Schema({
title: String,
url: String,
body: String,
votes: Number,
_comments: [{type: mongoose.Schema.Types.ObjectId, ref: "Comment"}]
});
const Post = mongoose.model('Post', postSchema);
module.exports = Post;
comment.js
const mongoose = require('mongoose');
const db = require('./init');
const commentSchema = new mongoose.Schema({
// post_id: post_id,
_post: { type: String, ref: 'Post'},
content: String,
posted: { type: Date, default: Date.now() }
});
const Comment = mongoose.model('Comment', commentSchema);
module.exports = Comment;
posts.js
router.get('/', function(req, res, next) {
// An empty find method will return all Posts
Post.find()
.populate('_comments')
.then(posts => {
res.json(posts)
})
.catch(err => {
res.json({ message: err.message })
})
});
and within the posts.js file I've set up a route to create a comment when a post request is sent to posts/post_id/comments
commentsRouter.post('/', function(req, res, next) {
console.log(req.params.id)
//res.json({response: 'hai'})
comment = new Comment;
comment.content = req.body.content;
comment._post = req.params.id
comment.save((err) => {
if (err)
res.send(err);
res.json({comment});
});
});
Comments are being created when I post to this route, and they are created with the correct _post value, however populate isn't picking them up.
For example, this post has been created, and it doesn't populate the associated comment below:
{
"post": {
"__v": 0,
"votes": 0,
"body": "Test Body",
"url": "Test URL",
"title": "Test Title",
"_id": "587f4b0a4e8c5b2879c63a8c",
"_comments": []
}
}
{
"comment": {
"__v": 0,
"_post": "587f4b0a4e8c5b2879c63a8c",
"content": "Test Comment Content",
"_id": "587f4b6a4e8c5b2879c63a8d",
"posted": "2017-01-18T10:37:55.935Z"
}
}
When you create a comment, you also have to save the comment instance _id to a post. So within the save() callback, you can do something like
commentsRouter.post('/', function(req, res, next) {
console.log(req.params.id)
//res.json({response: 'hai'})
comment = new Comment({
content: req.body.content;
_post: req.params.id
});
comment.save((err, doc) => {
if (err)
res.send(err);
Post.findByIdAndUpdate(req.params.id,
{ $push: { _comments: doc._id } },
{ new: true },
(err, post) => {
if (err)
res.send(err);
res.json({doc});
}
)
});
});

Resources