While creating api with nodejs, reference error: schema is not defined - node.js

I want to reach information with get method on Postman. But whenever i "localhost:3000/api/mekanlar/mekan's objectid", i get reference error "Mekan is not defined". Here is my mekansema.js file in /app_api/models.
var mongoose = require('mongoose');
var saatSema = new mongoose.Schema({
gunler: {type: String, required: true},
acilis: String,
kapanis: String,
kapali: {type: Boolean, required: true}
});
var yorumSema = new mongoose.Schema({
ad: String,
puan: {type: Number, required: true, min:0, max:5},
yorumMetni: String,
saat: {type: Date, default: Date.now}
});
var mekanSema = new mongoose.Schema({
ad: {type: String, required: true},
adres: String,
puan: {type: Number, default:0, min:0, max:5},
imkanlar: [String],
mesafe: {type: [Number], index:'2dsphere'},
saat: [saatSema],
yorumlar: [yorumSema]
});
mongoose.model('Mekan', mekanSema, 'Mekanlar');
and mekanlar.js file in /app_api/controllers
var mongoose = require('mongoose');
var mekan = mongoose.model('Mekan');
var jsonCevapYolla = function(res, status, content){
res.status(status);
res.json(content);
};
module.exports.mekanGetir = function(req, res){
if (req.params && req.params.mekanid){
Mekan
.findById(req.params.mekanid)
.exec(function(hata, mekan){
if(!mekan){
jsonCevapYolla(res, 404, {
"mesaj" : "mekanid bulunamadı."
});
return;
}
else if(hata){
jsonCevapYolla(res, 404, hata);
return;
}
jsonCevapYolla(res, 200, mekan);
});
}
else{
jsonCevapYolla(res, 404, {
"mesaj" : "istekte mekanid yok"
});
}
};
and this is index.js in /app_api/routes.
var express = require('express');
var router = express.Router();
var ctrlMekanlar = require('../controllers/mekanlar');
var ctrlYorumlar = require('../controllers/yorumlar');
//Mekan Rotaları
//router.get('/mekanlar', ctrlMekanlar.mekanlariListele);
//router.post('/mekanlar', ctrlMekanlar.mekanEkle);
router.get('/mekanlar/:mekanid', ctrlMekanlar.mekanGetir);
//router.put('/mekanlar/:mekanid', ctrlMekanlar.mekanGuncelle);
//router.delete('/mekanlar/:mekanid', ctrlMekanlar.mekanSil);
//Yorum Rotaları
//router.post('/mekanlar/:mekanid/yorumlar', ctrlYorumlar.yorumEkle);
//router.get('/mekanlar/:mekanid/yorumlar/:yorumid', ctrlYorumlar.yorumGetir);
//router.put('/mekanlar/:mekanid/yorumlar/:yorumid', ctrlYorumlar.yorumGuncelle);
//router.delete('/mekanlar/:mekanid/yorumlar/:yorumid', ctrlYorumlar.yorumSil);
module.exports = router;

it's difficult to see where the problem is, since you don't provide a stack trace. but I think at this line:
Mekan
.findById(req.params.mekanid)
Mekan should be mekan.

Related

Require one field, if another doesn't exists

To post a message to MongoDB i need to send a schema with a required text field. But even media field exists (as optional) - you can send request without text field. How should I do it? Here is a code:
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var Message = new Schema({
text: {type: String, required: true},
media: {type: Object, required: false}
})
You can try this using function validation as mentioned here
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var Message = new Schema({
text: {
type: String,
required: function() {
return !this.media;
}
},
media: {
type: Object,
required: function() {
return !this.text;
}
})

How to bind array of values to nodeJs model?

I am developing RESTful API.
Model
var productsSchema = new Schema({
productName:{type: String, required: true},
productDescription: {type: String, required: true},
produtThumbnail:{type: String},
productStock: [
{
size: {type: Number, required: false},
price: {type: Number, required: false}
}],
productTags:[{
tag: {type: String, required: false}
}]
});
POST Method
router.post('/api/new-product',upload.any(),function(req, res, next){
console.log(req.body);
if(req.files){
req.files.forEach(function(file){
var filename = (new Date()).valueOf() + '-' + file.originalname;
fs.rename(file.path,'public/images/'+ filename, function(err){
if (err) throw err;
console.log('file Uploaded');
//Save to mongoose
var product = new Products({
productName: req.body.productName,
productDescription: req.body.productDescription,
size: req.body.productStock.size,
productThumbnail: filename
});
product.save(function(err, result){
if(err){}
res.json(result);
});
});
});
}
}) <br/>
Problem:
I am able to bind object data to model, but I don't know how to bind array-data to model.
For example
var product = new Products({
productName: req.body.productName,
productDescription: req.body.productDescription,
size: req.body.productStock.size,// This line doesn't work
productThumbnail: filename
});
size:req.body.productStock doesn't work
So, How can I bind array-data to model, and then save it to mongodb?
Please help..
Just change it to type array
var productsSchema = new Schema({
merchantId: {type: String, required: false},
produtThumbnai:{type: String},
productStock: {type: Array},
productTags:{type: Array}
});
It Works!!
Maybe it's just because of a typo, because your Schema looks OK. Change this:
var product = new Products({
// ...
size: req.body.productStock.size,
// ...
});
To this:
var product = new Products({
// ...
productStock: req.body.productStock,
// ...
});
For this to work you should be passing your productStock as an array of objects from your POST request (!)
Otherwise it's a bit difficult to offer you more help, since we are unaware of what req.body actually is.
EDIT
To check if the above works (and assuming you are passing productStock as a whole array of objects from Postman/Curl/whatever), do the following and paste the result here:
product.productStock.foreach( (product, idx) => console.log(`(${idx}):${product.id}, `) )

Mongoose pre-save hook fires, but does not persist data

I am encountering a problem where my Mongoose pre.save() hook is firing, but the attribute does not get saved to the database. I have been searching for a long time without finding an answer.I found this thread, and the behaviour I am experiencing is very similiar, but OP's problem is related to the context of this, whereas I seem to have a different problem.
Here is my models.js:
'use strict';
const mongoose = require("mongoose");
const slugify = require("slugify");
let Schema = mongoose.Schema;
let BlogPostSchema = new Schema({
title: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
author: String,
post: {
type: String,
required: true
}
});
BlogPostSchema.pre('save', function(next) {
this.slug = slugify(this.title);
console.log(this.slug);
next();
});
// Passed to templates to generate url with slug.
BlogPostSchema.virtual("url").get(function() {
console.log(this.slug);
console.log(this.id);
return this.slug + "/" + this.id;
});
BlogPostSchema.set("toObject", {getters: true});
let BlogPost = mongoose.model("BlogPost", BlogPostSchema);
module.exports.BlogPost = BlogPost;
And here is the relevant lines in the router file index.js:
const express = require('express');
const router = express.Router();
const BlogPost = require("../models").BlogPost;
// Route for accepting new blog post
router.post("/new-blog-post", (req, res, next) => {
let blogPost = new BlogPost(req.body);
blogPost.save((err, blogPost) => {
if(err) return next(err);
res.status(201);
res.json(blogPost);
});
});
I am able to save the blog post to the database, and my console.log's correctly prints out the slug to the console. However, the this.slug in the pre-save hook does not get persisted in the database.
Can anybody see what the problem is here? Thank you so much in advance.
Mongoose will act according to the schema you defined.
Currently, your schema does not contain s filed named slug.
You should add a slug field to your schema.
Changing your current schema to something like this should work:
let BlogPostSchema = new Schema({
slug: String,
title: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
author: String,
post: {
type: String,
required: true
}
});

Nodejs include Models

Im having problems to make my server.js use my models.
I do have other models with same structure, like for example:
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
but they works fine.. somehow.
But if If i try to use:
var Crime = mongoose.model('Crime');
i get:
throw new mongoose.Error.MissingSchemaError(name);
^
MissingSchemaError: Schema hasn't been registered for model "Crime".
if i switch to:
var Crime = require('./models/Crime');
or
var Crime = require('./models/Crime.js');
i get the response:
Cannot find module './models/Crime'
Crime model code:
var mongoose = require('mongoose');
var CrimeSchema = new mongoose.Schema({
username: {type: String, lowercase: true, unique: true},
time: String,
salt: String
});
CrimeSchema.methods.performCrime = function(pass) {
/*var deferred = $q.defer();
deferred.notify('loading....');
deferred.reject('Greeting is not allowed.');
return deferred.promise;
*/
return 22;
};
mongoose.model('Crime', CrimeSchema);
EDIT
example of working model:
var Post = mongoose.model('Post');
and post.js model
var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
title: String,
link: String,
upvotes: {type: Number, default: 0},
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
PostSchema.methods.upvote = function(cb) {
this.upvotes += 1;
this.save(cb);
};
PostSchema.methods.downvote = function (cb) {
this.upvotes -= 1;
this.save(cb);
};
mongoose.model('Post', PostSchema);
You forgot to export the module at the end.
var Crime = mongoose.model('Crime', CrimeSchema);
module.exports = Crime;

TypeError object is not a function

I'm developing an application in node.js with MongoDB
I have to files:
product.js and displaycost.js
this is product .js:
var mongoose = require('mongoose');
var Category = require('./category');
var productSchema = {
name:{type: String, require: true},
//Pictures mus start with "http://"
pictures:[{type:String, match: /^http:\/\//i}],
price:{
amount:{type: Number, required: true},
//ONly 3 supported currencies for now
currency:{
type: String,
enum:['USD','EUR','GBP'],
required: true
}
},
category: Category.categorySchema
};
var schema = new mongoose.Schema(productSchema);
var currencySymbols ={
'USD': '$',
'EUR':'€',
'GBP':'£'
};
/*
*
*/
schema.virtual('displayPrice').get(function(){
return currencySymbols[this.price.currency] +
'' + this.price.amount;
});
schema.set('toObject', {virtuals:true});
schema.set('toJSON', {virtuals:true});
module.exports = schema;
What I need is create a record with "productSchema"
I tried with this:
var Product = require('./product.js');
var p = new Product({
name: 'test',
price:{
amount : 5,
currency: 'USD'
},
category: {
name: 'test'
}
});
console.log(p.displayPrice); // "$5"
p.price.amount = 20;
console.log(p.displayPrice); //" $20"
//{... "displayPrice: "$20",...}
console.log(JSON.stringify(p));
var obj = p.toObject();
But when I run the displaycost.js throw me an error at the word "new"
and writes "TypeError: object is not a function"
I don't know why is happening that. Thank you.
you missing export mongoose model with model name.
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
Category = require('./category');
var productSchema = new Schema({
name: {type: String, require: true},
pictures: [{type: String, match: /^http:\/\//i}],
price: {
amount: {type: Number, required: true},
currency: {
type: String,
enum: ['USD', 'EUR', 'GBP'],
required: true
}
},
category: Category
});
var currencySymbols = {
'USD': '$',
'EUR': '€',
'GBP': '£'
};
productSchema.virtual('displayPrice').get(function () {
return currencySymbols[this.price.currency] +
'' + this.price.amount;
});
productSchema.set('toObject', {virtuals: true});
productSchema.set('toJSON', {virtuals: true});
module.exports = mongoose.model('Product', productSchema);
"new" can only be called on a function. not an object.
In program.js you are creating a new instance of the mongoose schema.
var schema = new mongoose.Schema(productSchema);
... more code ...
return schema;
In your other js file you require product. At this point in time product.js has returned an object to you. A new mongoose schema. It is an object which you are refering to as Product.
You then try to create a new instance of it by calling new on the product OBJECT. New cannot be called on an object literal. It can only be called on a function.
I don't believe you need to make a new instance of schema within product.js, just return the function that creates the schema. Then call new on it when you require it like you are in your second file.

Resources