I sent below (raw/json) from postman to mongodb and I received filled img, text but coordinates was empty array "[]"
{
"coordinates": [],
"_id": "5b309b5671903722e073827e",
"date": "2018-06-25T07:35:50.932Z",
"__v": 0
},
Why is this is and how get not empty coordinates array?
Postman
{
"img": "test",
"text": "Meet",
"coordinates": [12, 23]
}
this is my schema
const mongoose = require('mongoose')
const memoSchema = new mongoose.Schema({
img: {
type: String
},
text: {
type: String
},
date: {
type: Date,
default: Date.now
},
coordinates: [Number]
})
module.exports = mongoose.model('Memo', memoSchema)
this is my router
api.post('/', async (req, res) => {
let newMemo = new Memo()
newMemo.img = req.body.img
newMemo.text = req.body.text
newMemo.coordinates = req.body.coordinates
await newMemo.save((err) => {
if(err) return res.status(500).json({ message: 'internal error' })
res.json({ message: 'saved...' })
})
})
I didn't add bodyparser
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
Related
I'm new to mongoose and mongodb.
I have two collection (cart and produk)
1 cart have 1 produk, and I get the cart and populate the product but is not show the data relations.
Here the code:
routing
router.route('/relations/:app_id')
.get(cartController.relation);
model (cartModel)
var mongoose = require('mongoose');
var cartSchema = mongoose.Schema({
app_id: {
type: String,
required: true
},
product_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Produk'
},
qty: Number
});
var collectionName = 'cart';
var Cart = module.exports = mongoose.model('Cart', cartSchema, collectionName);
module.exports.get = function (callback, limit) {
Cart.find(callback).limit(limit);
}
model (produkModel)
var mongoose = require('mongoose');
// Setup schema
var produkSchema = new Schema({
name: {
type: String,
required: true
},
stok: Number
});
// Export Cart model
var collectionName = 'produk';
var Produk = module.exports = mongoose.model('Produk', produkSchema, collectionName);
module.exports.get = function (callback, limit) {
Produk.find(callback).limit(limit);
}
controller (cartController)
Cart = require('../model/cartModel');
exports.relation = function (req, res) {
const showCart = async function() {
const carto = await Cart.find().select('app_id product_id qty').populate("produk");
return carto;
};
showCart()
.then(cs => {
return apiResponse.successResponseWithData(res, "Operation success", cs);
})
.catch(err => console.log(err));
};
// Result
{
"status": 1,
"message": "Operation success",
"data": [
{
"_id": "60af72022d57d542a41ffa5a",
"app_id": "CvR4dTTjC7qgr7gA2yoUnIJnjRXaYokD6uc2pkrp",
"qty": 1,
"product_id": "60112f3a25e6ba2369424ea3"
},
{
"_id": "60b020536ccea245b410fb38",
"app_id": "CvR4dTTjC7qgr7gA2yoUnIJnjRXaYokD6uc2pkrp",
"product_id": "603f5aff9437e12fe71e6d41",
"qty": 1
}
]
}
expecting result
{
"status": 1,
"message": "Operation success",
"data": [
{
"_id": "60af72022d57d542a41ffa5a",
"app_id": "CvR4dTTjC7qgr7gA2yoUnIJnjRXaYokD6uc2pkrp",
"qty": 1,
"product_id": {
"_id": "60112f3a25e6ba2369424ea3",
"name": "snack"
}
},
{
"_id": "60b020536ccea245b410fb38",
"app_id": "CvR4dTTjC7qgr7gA2yoUnIJnjRXaYokD6uc2pkrp",
"product_id": {
"_id": "603f5aff9437e12fe71e6d41",
"name": "snack"
}
"qty": 1
}
]
}
what I miss ???
Thanks for your help
You need to pass the path to populate or an object specifying parameters to .populate(). So in this case, Your code should be:
const carto = await Cart.find().select('app_id product_id qty').populate("product_id");
Good morning everyone, I'm having a bit of a struggle setting up a server to listen for webhook data and post it to a database. I'm mostly front-end, so some of this is a bit new for me. So I have a deli website that i built on snipcart. I have a receipt printer that queries an api and prints out new orders. So what I'm wanting is a server to listen for the webhook and store the info in a database. I've got it where it listens for the webhook correctly, but it refuses to post to the database. Here's the code in the app.js file.
'use strict';
require('./config/db');
const express = require('express');
const bodyParser = require('body-parser');
const fetch = require('node-fetch');
const app = express();
var routes = require('./api/routes/apiRoutes');
routes(app);
let orderToken;
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
app.listen(process.env.PORT || 8080);
app.post('/hook', (req, res) => {
orderToken = req.body.content.token;
console.log(orderToken);
const secret = "snipcart api key";
const apiFetch = async function(){
};
let buffered = new Buffer.from(secret);
let base64data = buffered.toString('base64');
const start = async function(){
const request = await fetch('https://app.snipcart.com/api/orders/'+orderToken, {
headers: {
'Authorization': `Basic ${base64data}`,
'Accept': 'application/json'
}
});
const result = await request.json();
console.log(result);
};
start();
res.status(200).end();
});
app.get('/', (req, res) => {
res.send('hello world')
});
Here's the code in my apiController.js file
const mongoose = require('mongoose'),
Order = mongoose.model('apiModel');
// listAllOrders function - To list all orders
exports.listAllOrders = (req, res) => {
api.find({}, (err, api) => {
if (err) {
res.status(500).send(err);
}
res.status(200).json(api);
});
};
// createNewOrder function - To create new Order
exports.createNewOrder = (req, res) => {
let newApi = new api (req.body);
newApi.save((err, api) => {
if (err) {
res.status(500).send(err);
}
res.status(201).json(api);
});
};
// deleteOrder function - To delete order by id
exports.deleteOrder = async ( req, res) => {
await api.deleteOne({ _id:req.params.id }, (err) => {
if (err) {
return res.status(404).send(err);
}
res.status(200).json({ message:"Order successfully deleted"});
});
};
and my apiModel.js file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ApiSchema = new Schema({
customerName: {
type:String,
required:true
},
customerPhone: {
type:String,
required:true
},
name: {
type:String,
required:true
},
orderNumber: {
type:String,
required:true
},
price: {
type:String,
required:true
},
customFields: {
type:Array,
required:false
},
});
module.exports = mongoose.model("apiModel", ApiSchema);
apiRoutes.js
module.exports = function(app){
var orderList = require('../controllers/apiController');
app
.route('/orders')
.get(orderList.listAllOrders)
.post(orderList.createNewOrder);
app
.route('/order/:id')
.delete(orderList.deleteOrder);
};
and my db.js
const mongoose = require("mongoose");
//Assign MongoDB connection string to Uri and declare options settings
var uri = "<mongodb atlas info>
retryWrites=true&w=majority";
// Declare a variable named option and assign optional settings
const options = {
useNewUrlParser: true,
useUnifiedTopology: true
};
// Connect MongoDB Atlas using mongoose connect method
mongoose.connect(uri, options).then(() => {
console.log("Database connection established!");
},
err => {
{
console.log("Error connecting Database instance due to:", err);
}
});
and here's a sample response that I need to place into the database
{
"token": "93c4604e-35ac-4db7-b3f1-2871476e9e6a",
"creationDate": "2013-10-22T20:54:40.377Z",
"modificationDate": "2013-10-22T20:55:45.617Z",
"status": "Processed",
"paymentMethod": "CreditCard",
"invoiceNumber": "SNIP-1427",
"email": "geeks#snipcart.com",
"cardHolderName": "Geeks Snipcart",
"creditCardLast4Digits": "4242",
"billingAddressName": "Geeks Snipcart",
"billingAddressCompanyName": "Snipcart",
"billingAddressAddress1": "4885 1ere Avenue",
"billingAddressAddress2": null,
"billingAddressCity": "Quebec",
"billingAddressCountry": "CA",
"billingAddressProvince": "QC",
"billingAddressPostalCode": "G1H2T5",
"billingAddressPhone": "1-877-301-4813",
"notes": null,
"shippingAddressName": "Geeks Snipcart",
"shippingAddressCompanyName": "Snipcart",
"shippingAddressAddress1": "4885 1ere Avenue",
"shippingAddressAddress2": null,
"shippingAddressCity": "Quebec",
"shippingAddressCountry": "CA",
"shippingAddressProvince": "QC",
"shippingAddressPostalCode": "G1H2T5",
"shippingAddressPhone": "1-877-301-4813",
"shippingAddressSameAsBilling": true,
"finalGrandTotal": 287.44,
"shippingFees": 10,
"shippingMethod": "Shipping",
"items": [
{
"uniqueId": "1aad3398-1260-419c-9af4-d18e6fe75fbf",
"id": "1",
"name": "Un poster",
"price": 300,
"quantity": 1,
"url": "http://snipcart.com",
"weight": 10,
"description": "Bacon",
"image": "",
"customFieldsJson": "[]",
"stackable": true,
"maxQuantity": null,
"totalPrice": 300,
"totalWeight": 10
},
...
],
"taxes": [
{
"taxName": "TPS",
"taxRate": 0.05,
"amount": 12.5,
"numberForInvoice": ""
},
{
"taxName": "TVQ",
"taxRate": 0.09975,
"amount": 24.94,
"numberForInvoice": ""
},
...
],
"rebateAmount": 0,
"subtotal": 310,
"itemsTotal": 300,
"grandTotal": 347.44,
"totalWeight": 10,
"hasPromocode": true,
"totalRebateRate": 20,
"promocodes": [
{
"code": "PROMO",
"name": "PROMO",
"type": "Rate",
"rate": 20,
},
...
],
"willBePaidLater": false,
"customFields": [
{
"name":"Slug",
"value": "An order"
},
...
],
"paymentTransactionId": null,
}
I dont need all the info placed in the database, just a few key items, like customer name, phone number and the order info. but if there's more than one item in the order, I need it to take that into account and add all the items in the order. here is the docs for the printer that i'm needing to integrate https://star-m.jp/products/s_print/CloudPRNTSDK/Documentation/en/index.html Would appreciate any help that you all can give me. Thanks!
Snipcart will send the webhook to you endpoint for different events. I would suggest you to first filter the event by eventName, because you want to listen for only the order.completed event. After that from the body of the request message, you can extract the items that will be in the req.body.content.items. You can take from the available info what you want and store only that in the database.
Try this:
app.post('/hook', (req, res) => {
if (req.body.eventName === 'order.completed') {
const customer_name = req.body.content.cardHolderName;
const customer_phone req.body.content.billingAddressPhone;
const order_number = req.body.content.invoiceNumber;
let items = [];
req.body.content.items.forEach((item) => {
items.push({
name: item.name,
price: item.price,
quantity: item.quantity,
id: item.uniqueId
});
})
// Now store in database
apiFetch.create({
customerName: customer_name,
customerPhone: customer_phone
name: customer_name,
orderNumber: order_number
customFields: items
}).then(()=>{
res.status(200).json({success:true});
}, (error)=>{
console.log('ERROR: ', error);
})
}
};
i am testing my mongoose (for MongoDB) schema, and I encountered an validation issue. After making POST verb I am getting en error:
"message": {
"errors": {
"number": {
"message": "Path `number` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `number` is required.",
"type": "required",
"path": "number"
},
"kind": "required",
"path": "number"
}
},
"_message": "eventArrayModel validation failed",
"message": "eventArrayModel validation failed: number: Path `number` is required.",
"name": "ValidationError"
}
This is my mocked json in Postman:
JSON mocked file
{
"arrayName": "displayedEvents",
"number": "4"
}
And this is my mongoose schema:
const mongoose = require("mongoose");
const eventSchema = new mongoose.Schema({
title: {
type: String,
// required: true,
},
start: {
type: Date,
// required: true,
},
end: {
type: Date,
// required: true,
},
allDay: {type: Boolean, default: true},
resource: {
type: String,
// required: true,
},
});
const eventArrayModel = mongoose.model("eventArrayModel", {
arrayName: {
type: String,
required: true,
},
array: {type: [eventSchema]} ,
number: {
type: Number,
required: true,
}
});
module.exports = eventArrayModel;
And the get router:
router.get('/', async (req,res)=> {
try{
const posts = await eventArrayModel.find();
res.json(posts);
}catch(err){
res.json({message: err});
}
});
I can't see anything wrong about this code. It works fine without number field.
Okey I found it, this part of code
router.post('/', async(req,res)=>{
const post = new eventArrayModel({
arrayName: req.body.arrayName
});
try {
const savedPost = await post.save();
res.json(savedPost);
}catch(err){
res.json({message: err});
}
});
Should looks more like this:
router.post('/', async(req,res)=>{
const post = new eventArrayModel({
arrayName: req.body.arrayName,
array: req.body.array,
myNumber: req.body.myNumber
});
try {
const savedPost = await post.save();
res.json(savedPost);
}catch(err){
res.json({message: err});
}
});
I'm using 3.6.5(mongodb) and trying to get documents near specified location like [-10, 20]...
When I tried get request "http://localhost:3030/ninjas?lng=-80&lat=20" it returns "unable to find index for $geoNear query"
I tried adding index(), changing query and searching official document but, failed.
please help!
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
app.use(bodyParser.json());
mongoose.connect("mongodb://localhost/gpsTest")
.then(() => console.log('Connected to MongoDB...'))
.catch(err => console.error(('Could not connect to MongoDB...\n'), err))
const NinjaSchema = new Schema({
name: {
type: String,
},
rank: {
type: String,
},
available: {
type: Boolean,
default: false
},
geometry: {
type: {
type: String,
default: "Point",
index: '2dsphere'
},
coordinates: {
type: [Number]
}
}
})
NinjaSchema.index({geometry: '2dsphere'});
const Ninja = mongoose.model('ninja', NinjaSchema);
app.post('/ninjas', (req, res) => {
Ninja.create(req.body).then(ninja => {
res.send(ninja);
})
})
app.get('/ninjas', (req, res) => {
Ninja.find({}).where('location').nearSphere({center: {
type: 'Point',
coordinates : [parseFloat(req.query.lng), parseFloat(req.query.lat)],
spherical: true
}}
).then(ninjas => {
res.send(ninjas);
});
})
app.listen(3030, () => {
console.log(`listening port: 3030`);
})
This one is for post request.
{ "name": "test", "rank": "red belt", "available": true,
"geometry" : {"type": "Point", "coordinates": [-80, 27]} }
This is because of typo...
Should change
Ninja.find({}).where('location').nearSphere({center: {...
to
Ninja.find({}).where('geometry').nearSphere({center: {...
I try to create valid geojson FeatureCollection and some problems occurred during updating document in collection.
My Model
var mongoose = require('mongoose');
Schema = mongoose.Schema;
var DataSchema = new Schema({
type: {type:String, default:"Feature"},
properties:{
title: { type: String, required: true },
description: { type: String, required: true},
date: {type:Date, default:Date.now}},
geometry:{
type:{type:String, default:"Point"},
coordinates: {type: [Number]}}
});
var MetadataSchema = new mongoose.Schema({
type : {type: String, default: "FeatureCollection"},
features: [DataSchema]
});
var rescueModel = mongoose.model('rescueModel', MetadataSchema);
Router
router.post('/mountain_rescue', function(req, res){
db.collection('rescuemodels', function(err, collection){
collection.update({
"type": "FeatureCollection"
},
{
$push: {
"features": {
properties: {
title: req.body.title,
description: req.body.description
},
geometry: {
coordinates: req.body.coordinates.split(',')
}
}
}
});
res.redirect('/mountain_rescue');
});
});
module.exports=rescueModel;
So If everything is okay but why is it that after executing post route I get
TypeError: Cannot call method 'update' of undefined
I also checked the command in mongo shell and it works
db.rescuemodels.update(
{
"type":"FeatureCollection"
},
{
$push:{
"features": {
"properties":{"title":"WOW"}
}
}
}
)
The problem is that collection is not defined before running the update. Also, you might want to do the redirect in the callback to the update function, but that will depend on the behaviour you are looking for. Your code would then look something like this:
var collection = db.collection('rescuemodels');
collection.update({
"type": "FeatureCollection"
},
{
"$push": {
"features": {
"properties": {
"title": req.body.title,
"description": req.body.description
},
"geometry": {
"coordinates": req.body.coordinates.split(',')
}
}
}
}, function(err, result) {
if (err) throw err;
res.redirect('/mountain_rescue');
});