Mongoose.create creating document but none of my data - node.js

I'm learning to use the mean stack and trying to build a url shortener. I've got a module that takes the req.params.UserUrl checks and makes sure it's a valid url then creates a random number that I want to use as the short route. I can't seem to find a way to save the random number so that I can check their next url request against it. After a google search it seemed maybe the most effecient way would be to save an object in the database with the long_url and the short_url:randomNumber. My code doesn't throw any errors but when I check my heroku database it has a new entry but only has the _id and __v that mLabs generates itself. Can someone tell me where I'm going wrong.
Route File
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var URLShortener = require(process.cwd()+'/public/Modules/urlShortener.module.js');
var ShortURL = require('../models/shortUrl.js');
router.get('/', function(req, res) {
res.render('index', { title: 'FreeCodeCamp Projects' });
});
router.get('/urlShortener', function(req, res){
res.render('freecodecamp/urlShortener', { title: 'Url Shortener Site'});
});
router.get('/urlShortener/:userUrl', function(req, res){
if(URLShortener.checkValidUrl(req.params.userUrl))
{
var UserUrl = req.params.userUrl;
var randNbr = URLShortener.assignRanNbr();
ShortURL.create(URLShortener.createUrlObj(UserUrl, randNbr), function (err, smallUrl) {
if (err) return console.log(err);
else res.json(smallUrl);
});
}
else
{
res.send('Invalid url');
}
});
router.get('/:short', function(req, res){
if(randNbr == req.params.short)
{
res.redirect(userUrl);
}
else
{
res.send('Not the correct shortcut');
}
});
module.exports = router;
Url Schema
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var shortUrlSchema = new Schema({
long_id:String,
short_id:Number
}, {collection: 'shortUrl'});
module.exports = mongoose.model('shortUrl', shortUrlSchema);
urlShortener Module
'use strict'
module.exports.checkValidUrl = function(url){
var pattern = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+#)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%#.\w_]*)#?(?:[\w]*))?)/);
return pattern.test(url);
}
module.exports.assignRanNbr = function(){
var randNbr = Math.floor(Math.random() * (9999 - 1 + 1)) + 1;
return randNbr;
}
module.exports.createUrlObj = function(url, num){
var urlObj = {};
urlObj.original_url = url;
urlObj.short_url = 'https://rawlejuglal-me-rawlejuglal-1.c9users.io/freecodecamp/'+num;
return urlObj;
}

Your createUrlObj method is returning an object with the properties original_url and short_url, but your shortUrlSchema properties are long_id and short_id. The property names in your create method need to match your schema. The property value types must also match your schema types (currently short_url is a string and short_id is a number). I think what you really want is for your createUrlObj method to be
module.exports.createUrlObj = function(url, num){
var urlObj = {};
urlObj.long_url = url;
urlObj.short_id = num;
return urlObj;
}
and your schema to be
var shortUrlSchema = new mongoose.Schema({
long_url: String,
short_id: Number
}, {collection: 'shortUrl'});
Additionally, your '/:short' route should have a call to the database since the randNbr and userUrl variables are not defined in that route.
router.get('/:short', function(req, res){
ShortUrl.findOne({short_id: req.params.short}, function(err, shortUrl){
if(err) res.send('Invalid Url');
res.redirect(shortUrl.long_url)
})
});

Related

Multiple queries in documentdb-q-promises for Nodejs

I want to render a page getting info for two different queries in CosmoDB using documentdb.
I have 2 queries:
var FirstQuery = {
query: 'SELECT * FROM FactoryData',
};
var SecondQuery = {
query: 'SELECT * FROM StoreData',
};
And have this to get the data
docDbClient.queryDocuments(collLink, FirstQuery ).toArray(function (err, results) {
value1 = results;
});
docDbClient.queryDocuments(collLink, SecondQuery ).toArray(function (err, results) {
value2 = results;
});
then i want to render the view with those results but i cant get it rendering from outise of this funcions.
res.render('view.html', {"value1" : value1 , "value2" : value2});
I know that this code will not work, but i was trying to implement promises and didn't know how to do it with documentdb-q-promises.
I already read a lot of documentation about Q promise but i dont get it.
Can someone explain to me how i can do it , I`m a beginner.
Based on your requirements,I followed the npm doc and test code on github to test following code in my local express project. Please refer to it.
var express = require('express');
var router = express.Router();
var DocumentClient = require('documentdb-q-promises').DocumentClientWrapper;
var host = 'https://***.documents.azure.com:443/'; // Add your endpoint
var masterKey = '***'; // Add the massterkey of the endpoint
var client = new DocumentClient(host, {masterKey: masterKey});
var collLink1 = 'dbs/db/colls/import';
var FirstQuery = 'select c.id,c.name from c';
var collLink2 = 'dbs/db/colls/item';
var returnArray = [];
client.queryDocuments(collLink1, FirstQuery).toArrayAsync().
then(function(response){
console.log(response.feed);
var map = {};
map['value1'] = response.feed;
returnArray.push(map);
return client.queryDocuments(collLink2, FirstQuery).toArrayAsync()
})
.then(function(response) {
console.log(response.feed);
var map = {};
map['value2'] = response.feed;
returnArray.push(map);
})
.fail(function(error) {
console.log("An error occured", error);
});
router.get('/', function(req, res, next) {
res.send(returnArray);
});
module.exports = router;
Test Result:
Hope it helps you.

NodeJs + MongoDB: return the document by it parameter

This is my structure of MongoDB:
I wanna make a query that return all keys and values of 1 Document in the database. I should select the document where a key "content-transition" is "ciao".
This is my code:
var router = express.Router();
const MongoCient = require('mongodb').MongoClient;
const dbName = 'myproject';
const url = 'mongodb://localhost:27017';
router.get('/get/:id', function (req, res) {
var param = req.params.id;
var myQuery = {
"content-transition":param
};
MongoClient.connect(url, function(err, client) {
var collection = client.db(dbName).collection('documents');
var result = collection.find({myQuery});
console.log(result)
});
});
I want return in the console the document into the variable "result" in relation by input parameter.
This code is written in NodeJs with che ExpressJs library.
if myQuery is defined as { "content-transition": param },
and you're calling collection.find({myQuery}),
then what you're really doing is
collection.find({ myQuery: { "content-transition": param }});
and of course mongo has no idea what to do with that.
try removing the curly brackets around myQuery when you call collection.find().

NodeJS: Use a pug template to display results

I have a method in a NodeJS app that handles scraping a URL, and when successful, saving that data in a Mongo database, and showing the results.
Main method:
//url parameter
app.get('/urls/', function(req, res) {
var client = new MetaInspector(req.query.url, {
timeout: 5000
});
client.on("fetch", function() {
var imagesArray = [];
var keywordsArray = [];
var now = new Date();
var dateVal = dateFormat(now, "mm/dd/yyyy h:MM:ss");
for (var i = 0; i < client.images.length; i++) {
// we only want jpgs. nothing else.
if (client.images[i].indexOf('.jpg') > -1) {
imagesArray.push({
"image": client.images[i]
})
}
}
for (var i = 0; i < client.keywords.length; i++) {
keywordsArray.push({
"keyword": client.keywords[i]
})
}
var newUrls = Urls({
url: client.url,
date_added: dateVal,
keywords: req.body.keywords,
author: client.author,
description: client.description,
ogTitle: client.ogTitle,
ogDescription: client.ogDescription,
image: client.image,
images: imagesArray,
keywords: keywordsArray
});
newUrls.save(function(err) {
if (err) throw err;
res.send('Success' + newUrls);
});
});
client.on("error", function(err) {
console.log(err);
});
client.fetch();
});
This all works well and good. But I'm using Pug and Express and have specific routes setup. I'd like instead of sending the newUrls obj to the res.send, have it go to a particular route and pass it to a particular pug template I already have setup:
// Route.js
var express = require('express');
var router = express.Router();
var Urls = require('../models/urlModel');
var Footer = require('../models/footerModel');
/* URL Saved Success Page */
router.get('/saved', function (req, res) {});
});
module.exports = router;
My view lives in a pug file located at:
/views/saved.pug
div#body
include nav.pug
div.container.item-container
div.row
div.col-md-8
h1 Item successfully saved.
h5 {item}
h6 {description}
I've tried using the res.send method, but that doesn't work. Any suggestions on how to handle this?
For my understanding, you want the request redirected to /saved with payload after urls saved to database, in this scenario, you could user res.redirect with query string
newUrls.save(function(err){
var payload = JSON.stringify({
url: client.url,
date_added: dateVal,
keywords: req.body.keywords,
author: client.author,
description: client.description,
ogTitle: client.ogTitle,
ogDescription: client.ogDescription,
image: client.image,
images: imagesArray,
keywords: keywordsArray
})
//append the payload as a query string
res.redirect(`/saved?payload=${payload}`)
})
and in /saved route, you could parse the query and use res.render
router.get('/saved', function (req, res) {});
let payload = JSON.parse(req.query.payload);
if(payload){
res.render('saved', payload)
}
});

How to perform bulk upload in mongoose (node.js)

I am trying to perform bulk upload in node js and mongodb is my db,can anyone suggest me some best articles regarding this.Thanks in advance.
You can use Model.collection.insert or Model.insertMany as below where collections is array of items in bulk.
Model.collection.insert(collections, function (err, models) {
next(err, models);
});
OR,
Model.insertMany(collections, function (err, models) {
next(err, models);
});
Mongoose reference: http://mongoosejs.com/docs/api.html#model_Model.insertMany
Mongo reference: https://docs.mongodb.com/v3.2/reference/method/db.collection.insert/
You can insert multiple records with batch/bulk insert in mongoose.
var arr = [{ name: 'Star Wars' }, { name: 'The Empire Strikes Back' }];
Movies.insertMany(arr, function(error, docs) {});
Let's say i have an excel file employees.xlsx with following data and i want perform bulk write.
There are several libraries out there for converting excel data to json in node, i use xlsx but it's personal taste you can use whatever is convenient for you.
Here is a helper i use for reading "/public/employees.xlsx" file.I found the content from here here.
//** helper/excel-reader.js **//
var excelReader = {};
excelReader.readExcel = function(filePath){
var XLSX = require('xlsx');
var workbook = XLSX.readFile(filePath);
var sheet_name_list = workbook.SheetNames;
var data = [];
sheet_name_list.forEach(function(y) {
var worksheet = workbook.Sheets[y];
var headers = {};
for(z in worksheet) {
if(z[0] === '!') continue;
//parse out the column, row, and value
var tt = 0;
for (var i = 0; i < z.length; i++) {
if (!isNaN(z[i])) {
tt = i;
break;
}
};
var col = z.substring(0,tt);
var row = parseInt(z.substring(tt));
var value = worksheet[z].v;
//store header names
if(row == 1 && value) {
headers[col] = value;
continue;
}
if(!data[row]) data[row]={};
data[row][headers[col]] = value;
}
//drop those first two rows which are empty
data.shift();
data.shift();
});
return data;
}
module.exports = excelReader;
Now the employee model somehow looks like this.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var employee = new Schema({
name: String,
adderess: String,
phonenumber: String
});
module.exports = mongoose.model('Employee', employee);
Now let's use the above code so here is my users.js route whenever i type "localhost:3000/users" it write the csv content to database.
var express = require('express');
var router = express.Router();
var excelReader = require('../helpers/excel-reader');
var mongoose = require('mongoose');
var Employee = require('../models/employee');
/* GET users listing. */
router.get('/', function(req, res, next) {
var employeesJsonArray = excelReader.readExcel('./public/employees.xlsx')
Employee.insertMany(employeesJsonArray,function(error, docs) {
if(error){
next(error)
}
else{
res.json(docs);//just rendering the document i got
}
});
});
module.exports = router;
Hope this helps!!

NodeJS Mongoose Not Save Data

My system will create around 30 collection for every hour. My server get thousands request for one hour. I have big data and multiple collections. And i use MongoDB-NodeJS for saving data.
The modelControl function of pariteModel class at the paritemodel.js -as the below codes- i do check if this schema is created before. And i will create schema or use created schema.
First collections creating and saving data to MongoDB. But when create another collections it's not doing. For example:
EURJPY_20160107_16 collection is created but EURJPY_20160107_17 collection is not create. I have check mongoose.models at modelparite.js EURJPY_20160107_17 is created but instance created from EURJPY_20160107_17 Schema not saved to database.
My server files like this:
app.js file is my bootstrap file:
var http = require('http'),
dispatcher = require('httpdispatcher');
require('./mongo.js');
function handleRequest(request, response){
try {
dispatcher.dispatch(request, response);
} catch(err) {
console.log(err);
}
}
var server = http.createServer(handleRequest);
server.listen(3663, function(){
console.log('listening the port: ' + 3663);
});
This is mongo.js which i call in app.js. This file uses for save data to mongodb:
var dispatcher = require('httpdispatcher'),
url = require('url'),
moment = require('moment'),
md = moment().format("YYYYMMDD_HH"),
myModel = require('./modelparite.js');
dispatcher.onGet('/mongo', function(req, res){
var url_parts = url.parse(req.url, true);
// This is collection name. Output like this: USDTRY_20160107_16
var colName = url_parts.query.symbol + '_' + md;
var tarih = new Date();
var pariteModel = myModel.returnModel(colName);
var yeniParite = new pariteModel({
symbol: url_parts.query.symbol,
bid: url_parts.query.bid,
ask: url_parts.query.ask,
timeup: moment(tarih).format("YYYY-MM-DD HH:mm:ss")
});
yeniParite.save(function (err, data) {
if (err) console.log(err);
console.dir(data,true);
});
res.writeHead(200, {'Content-Type': 'text/html'});
res.end();
});
And this is my model modelparite.js file which i call in mongo.js. This file uses to create schema with Mongoose:
var mongoose = require('mongoose'),
helper = require('./helper.js');
require('mongoose-double')(mongoose);
mongoose.connect('mongodb://localhost:27017/forex');
var pariteModel = {
pariteSchema: "",
initSchema: function(){
var Schema = mongoose.Schema;
this.pariteSchema = new Schema({
symbol: String,
bid: mongoose.Schema.Types.Double,
ask: mongoose.Schema.Types.Double,
timeup: Date
});
},
modelControl: function(modelName){
if(mongoose.models[modelName]){
return true;
}
return false;
},
returnModel: function(modelName){
modelName = helper.whichParity(modelName);
//console.log(modelName);
if(this.modelControl(modelName)){
//console.log(mongoose.model(modelName));
return mongoose.model(modelName);
}else{
this.initSchema();
return mongoose.model(modelName, this.pariteSchema);
}
},
}
module.exports = pariteModel;

Resources