I'm a beginner student of node js and i'm developing a simple inventory app. In my code, I'm currently using the MVC architecture, EJS as the template engine and MongoDB as the data base.
When I try to iterate over the resulting .find({}) method array in the EJS file, it seems like I get an empty array and no errors.
Basically, this is what I've tried:
MODEL:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
productInstanceSchema = new Schema({
product:{type: Schema.Types.ObjectId,ref: "RawProduct"},
date_added: {type: Date,required:true},
price:{type: Number, required:true},
expiration_date: {type:Date}
});
productInstanceSchema.virtual("url").get(function () {
return `product/productinstance/${this._id}`;
});
module.exports = mongoose.model("ProductInstance", productInstanceSchema);
CONTROLLER:
const RawProduct = require('../models/raw_product');
const ProductInstance = require('../models/productinstance');
exports.productinstances_byproduct = function (req,res,next) {
ProductInstance.find({})
.populate("product")
.exec(function (err, product_instances) {
if (err){
return next(err);
};
res.render('inventory', {instances:product_instances})
})
}
VIEW (.ejs file):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>ESTOQUE</h1>
<ul>
<% instances.forEach(function(instance) { %>
<li>
product: <%= instance.product %>
</li>
<% }); %>
</ul>
</body>
</html>
when I execute the route, I get an empty result:
Can you guys please help me find what is wrong with my code?
EDIT:
as suggested, I've made a test Script to log the results of the .find() method in the console and this is the result:
[
{
_id: new ObjectId("63399c7664a90dd9edc43c58"),
product: {
_id: new ObjectId("63399c7664a90dd9edc43c56"),
name: 'Batata-Frita',
description: 'BATATA PRÉ-FRITA TRADICIONAL CONGELADA MCCAIN PACOTE 1,5KG',
category: new ObjectId("63399c7664a90dd9edc43c54"),
EAN: '7797906000892',
unit: 'kg',
brand: 'McCain',
ideal_ammount: 5,
__v: 0
},
date_added: 2022-10-02T14:13:10.239Z,
price: 14.99,
expiration_date: 2022-10-15T00:00:00.000Z,
__v: 0
}
]
And, briefly, here is how I add data to the product instance:
function productInstanceCreate(product, date_added, price, expiration_date, cb) {
var productinstance = new ProductInstance({
product: product,
date_added: date_added,
price: price,
expiration_date: expiration_date
});
productinstance.save(function (err) {
if (err) {
cb(err, null)
return
}
console.log('New Product Instace: ' + productinstance);
productinstances.push(productinstance)
cb(null, productinstance)
} );
};
function createProductInstance(cb) {
async.series([
function(callback) {
productInstanceCreate(rawproducts[0],new Date, 14.99,'2022-10-15', callback);
},
], cb);
};
I use async series to control the flow and make sure categories and raw products are created before product instance
I know this is rare....,
Make sure the ObjectID saved there from the RawProduct.
Let me know if they are.
that was my case.
mongoose will check ObjectId of the product field and will search in the RawProduct collection.
can you check your database and post it?
I suggest reading the docs: Population
We just needed to write instance.product.name
Because product is Object type (:
Related
I am writing a shopify application using node platform, I am trying to get discount info in shopify from my application using the npm module "shopify-node-api", it shows "404- Not Found" error, but, I am able to get products and custom_collections by this method.
var Shopify = require('shopify-node-api');
var config = {};
config.shop = myshop.myshopify.com;
config.shopify_api_key = XXXX;
config.shopify_shared_secret = XXXX;
config.access_token = XXXX;
sails.log.verbose('Shopify config object: ', config);
var shopify = new Shopify(config);
shopify.get('/admin/discounts.json', function(err, data)
if (err) {
sails.log.error("Error in getDiscount ", err);
} else {
sails.log.verbose(" shopify.getDiscount data ", data);
}
Also I able to get discount details using the URL https://myshop.myshopify.com/admin/discounts.json and the output as
{
discounts: [
{
id: 4128341132,
code: "GET4PRODUCT",
value: "10.00",
ends_at: null,
starts_at: "2017-03-09T00:00:00-08:00",
status: "enabled",
minimum_order_amount: "0.00",
usage_limit: null,
applies_to_id: 9720854796,
applies_once: true,
applies_once_per_customer: true,
discount_type: "fixed_amount",
applies_to_resource: "product",
times_used: 0,
applies_to: {
id: 9720854796,
title: "xxxxxxxxxxxxxx",
body_html: "<meta content="text/html; charset=utf-8" http-equiv="content-type">
<ul class="a-vertical a-spacing-none">
<li><span class="a-list-item">Outer Material: EVA Sheet</span></li>
<li><span class="a-list-item">Sole Material: Anti Slip EVA Sole</span></li>
</ul>",
vendor: "myshop",
product_type: "",
created_at: "2017-02-18T05:24:52-08:00",
handle: "adreno-mens-blue-slippers",
updated_at: "2017-02-18T05:28:20-08:00",
published_at: "2017-02-18T05:23:00-08:00",
template_suffix: null,
published_scope: "global",
tags: ""
}
}
]
}
But I unable to get discount objects using my application. Do I need to provide any other credentials or is there any other method to get the discount object from my application.
Please help me for getting discount json from an application.
HymnZ is correct, the Discounts endpoint is only API-accessible for Plus store accounts.
If you are not a Plus subscriber, you can access the Discounts endpoint in your browser with an admin-authenticated session, but not using API credentials.
Is there a way for MongoDB to search an entire collection's keys' contents using only a single search keyword?
Suppose I have the following collection (let's call it foodCollection):
{
name: "Chocolate Mousse Cake",
type: "Cake"
},
{
name: "Mother's Cookies",
type: "Cookies"
},
{
name: "Dark Bar",
type: "Chocolate"
}
I want my search to look for matches that contain "Chocolate", meaning it should return "Chocolate Mousse Cake" and "Dark Bar".
I'm trying to do this using the ff: code:
Client-side controller
// Search Products
$scope.searchProduct = function () {
$http.get('/api/products/search/' + $scope.searchKeyword).success(function(data){
console.log(data);
})
.error(function(err) {
console.log("Search error: " + err);
});
}
Express.js
app.get('/api/products/search/:param', productController.search); // Search for product
Server-side controller (I used this reference from the MongoDB docs):
// Search
module.exports.search = function(req, res) {
console.log("node search: " + req.body);
Product.find({ $or: [{productName: req.body},
{productType: req.body}]
}, function(err, results) {
res.json(results);
});
}
When I executed this, I got nothing. Am I missing something?
Any help would be greatly appreciated. Thank you.
UPDATE (FINAL)
Finally solved this thanks to Joydip's and digit's tips. Here's my solution in case somebody else gets the same problem as I did:
Client-side controller
$scope.searchProduct = function () {
if ($scope.searchKeyword == '') {
loadFromMongoDB(); // reloads original list if keyword is blank
}
else {
$http.get('/api/products/search/' + $scope.searchKeyword).success(function(data){
if (data.length === 0) {
$scope.showNoRec = true; // my flag that triggers "No record found" message in UI
}
else {
$scope.showNoRec = false;
$scope.productList = data; // passes JSON search results to UI
}
});
}
}
Express.js
app.get('/api/products/search/:keyword', productController.search); // Search for product
Mongoose schema
var mongoose = require('mongoose');
var schema = new mongoose.Schema({
productName: String,
productType: String,
productMaker: String,
productPrice: Number,
createDate: Date,
updateDate: Date
});
schema.index({productName: "text", productType: "text", productMaker: "text"});
Server-side controller
module.exports.search = function(req, res) {
Product.find({$text: {$search : req.params.keyword}}, function(err, results){
res.json(results);
})
}
Thank you everyone for your help. :)
You can try by creating an Index:
db.yourollection.createIndex({"productName":1,"productType":1})
And then by searching for the value, Example:
Product.find({$text:{$search: 'Chocolate'}},{productName:1, productType:1});
If you want to search all key, then you can use
db.foodCollection.createIndex( { name: "text", description: "text" } )
then search by
db.foodCollection.find({ $text: { $search: "choco" } })
I am trying to pass the results from a MongoDB query to use in a Javascript file in my view. I am using handlebars as my view engine. My MongoDB schema is:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schema = new Schema({
name: {type: String, required: true},
address: {type: String, required: true},
lat: {type: String},
lng: {type: String},
classes: [{
day: String,
start: String,
end: String
}]
});
module.exports = mongoose.model('Dojo', schema);
My routing file has the following:
router.get('/classes', function(req, res, next) {
Dojo.find(function(err, dojos) {
if (err) {
console.error(err);
}
res.render('admin/classes', {
layout: 'layout-admin.hbs',
title: 'Admin',
js: 'classes-admin',
dojos: dojos
});
});
});
Within my hbs file, I have:
<p>{{ dojos }}</p>
The code above shows my variable on the screen OK but when I try to console.log this within script tags I get an Uncaught SyntaxError. My code is:
<script type="text/javascript">
console.log({{ dojos }});
</script>
Any advice on where I'm going wrong would be great appreciated.
Thanks
Matt
Try to change script tag:
<script type="text/javascript">
var mongo_result = {{dojos}};
console.log({{ mongo_result }});
</script>
I ended up switching to EJS as my template engine and used var dojos = <%- JSON.stringify(dojos) %>; which worked great.
I am creating an application in node.js utilizing the sails framework. I want to create a report in PDF format. The report needs to contain a chart generated using chart.js. The data is fetched from mongodb and displayed on a canvas. How can I create a PDF file of this chart using node.js?
You can use pdf-creator-node package to create PDF
Following are the steps to create PDF in Node Application
Installation install the pdf creator package by the following command
npm i pdf-creator-node
Add required packages and read HTML template
//Required package
var pdf = require("pdf-creator-node")
var fs = require('fs')
// Read HTML Template
var html = fs.readFileSync('template.html', 'utf8')
Create your HTML Template
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<h1>User List</h1>
<ul>
{{#each users}}
<li>Name: {{this.name}}</li>
<li>Age: {{this.age}}</li>
<br>
{{/each}}
</ul>
</body>
</html>
Provide Format and Orientation as per your need
"height": "10.5in", // allowed units: mm, cm, in, px
"width": "8in", // allowed units: mm, cm, in, px
or -
"format": "Letter", // allowed units: A3, A4, A5, Legal, Letter, Tabloid
"orientation": "portrait", // portrait or landscape
var options = {
format: "A3",
orientation: "portrait",
border: "10mm"
};
Provide HTML, User data and pdf path for the output
var users = [
{
name:"Shyam",
age:"26"
},
{
name:"Navjot",
age:"26"
},
{
name:"Vitthal",
age:"26"
}
]
var document = {
html: html,
data: {
users: users
},
path: "./output.pdf"
};
After setting all parameters just pass document and options to pdf.create method.
pdf.create(document, options)
.then(res => {
console.log(res)
})
.catch(error => {
console.error(error)
});
PDFKit.
Installation:
npm install pdfkit
Example:
var PDFDocument = require('pdfkit');
doc = new PDFDocument;
doc.pipe(fs.createWriteStream('output.pdf'));
doc.font('fonts/PalatinoBold.ttf').fontSize(25).text(100, 100);
The simplest way to generate PDFs using NodeJS is to use the pdf-master package.
You can generate static and dynamic PDFs using HTML with one function call.
Installation
npm install pdf-master
Example
Step 1 - Add required packages and generate a PDF
const express = require("express");
const pdfMaster = require("pdf-master");
const app = express();
app.get("", async (req, res) => {
var PDF = await pdfMaster.generatePdf("template.hbs");
res.contentType("application/pdf");
res.status(200).send(PDF);
});
generatePdf() syntax and parameters
generatePdf(
templatePath, //<string>
data, //<object> Pass data to template(optional)
options //<object> PDF format options(optional)
);
Step 2 - Create your HTML Template (save the template with .hbs extension instead of .html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Render dynamic data in template and PDF format options
const express = require("express");
const pdfMaster = require("pdf-master");
const app = express();
app.get("", async (req, res) => {
var students = {
{
id: 1,
name: "Sam",
age: 21
},
{
id: 2,
name: "Jhon",
age: 20
},
{
id: 3,
name: "Jim",
age: 24
}
}
let options = {
displayHeaderFooter: true,
format: "A4",
headerTemplate: `<h3> Header </h3>`,
footerTemplate: `<h3> Copyright 2023 </h3>`,
margin: { top: "80px", bottom: "100px" },
};
let PDF = await pdfMaster.generatePdf("template.hbs", students, options);
res.contentType("application/pdf");
res.status(200).send(PDF);
});
To learn more about pdf-master visit
A webpage sends JSON data via POST to my Node.js App (MEAN-environment using Mongoose). The JSON file looks like this (excerpt):
Firstname: 'XY',
Surname: 'asd',
Articles:
[ { title: '1', description: 'XY' },
{ title: '2', description: 'XY' },
{ title: '3', description: 'XY' }
The purpose is to create an Author in a mongodb database, add the author to an additional directory, store associated articles and create references to those articles in the author document (code excluded). This is the code that handles the request:
[...]
async.waterfall([
//Create random code for author (besides mongodb-specific id)
function(callback){
newAuthorCode.randomAuthorCode(function(err, code) {
callback(null, code);
});
},
//Save new author to db
function(code, callback){
var newAuthor = new Author({firstname: req.body.Firstname,
surname: req.body.Surname,
identcode: code
});
newAuthor.save(function (err){
callback(null, newAuthor);
});
},
//Add new author to an additional directory
function(newAuthor, callback){
Directory.update({_id: req.user._id}, {$push: {authorids: newAuthor._id }}, function(err, update){
if (update){
callback(null);
}
});
},
//saves articles to db
function(callback){
var keys = Object.keys(req.body.articles);
for(var i=0, length=keys.length; i<length; i++){
var newArticle = new Article({title: req.body.Articles[keys[i]].title,
description: req.body.Articles[keys[i]].description
});
newArticle.save(function (err){
console.log(newArticle._id); // <--- !!!!!!!
});
}
callback(null);
}
], function (err, result) {
console.log('DONE!!!');
res.send('200');
});
My problems:
1) The marked line of code where I try to output all IDs of the generated articles only delivers i-times the ID of the last article stored (in this case of article 3).
2) Problem 1 leads to the issue that I can not create references of the newly created articles in the author document (stored in a different collection) as I can't access no article IDs but the last one!?
3) Sometimes the author, as well as the articles, are created multiple times in the database (with huge time gap in between)!?
Thanks for any advice as I am running out of ideas.
Igor
Not sure what newLink is in your code, but you can try this instead:
newArticle.save(function (err, newDoc){
console.log(newDoc._id); // <--- !!!!!!!
});