I'm studying a build full stack JavaScript apps with the MEAN stack, using Node.js, AngularJS, Express and MongoDB.
I'm in the third section where I have to retrieve all the hotels in my database.
When in the browser I type http: // localhost: 3000 / api / hotels /, my database returns an empty array, but the hotel.data.json file is full.
I also tried a copied section5's teacher's final work, but I have the same result, my database is empty [].
This is the code of the hotels.controllers file:
var mongoose = require('mongoose');
var Hotel = mongoose.model('Hotel');
module.exports.hotelsGetAll = function(req, res) {
console.log('GET the hotels');
console.log(req.query);
var offset = 0;
var count = 5;
if (req.query && req.query.offset) {
offset = parseInt(req.query.offset, 10);
}
if (req.query && req.query.count) {
count = parseInt(req.query.count, 10);
}
Hotel
.find()
.skip(offset)
.limit(count)
.exec(function(err, hotels) {
console.log("Found hotels", hotels.length);
res
.json(hotels);
});
};
module.exports.hotelsGetOne = function(req, res) {
var id = req.params.hotelId;
console.log('GET hotelId', id);
Hotel
.findById(id)
.exec(function(err, doc) {
res
.status(200)
.json(doc);
});
};
module.exports.hotelsAddOne = function(req, res) {
console.log("POST new hotel");
var db = dbconn.get();
var collection = db.collection('hotels');
var newHotel;
if (req.body && req.body.name && req.body.stars) {
newHotel = req.body;
newHotel.stars = parseInt(req.body.stars, 10);
collection.insertOne(newHotel, function(err, response) {
console.log("Hotel added", response);
console.log("Hotel added", response.ops);
res
.status(201)
.json(response.ops);
});
// console.log(newHotel);
// res
// .status(200)
// .json(newHotel);
} else {
console.log("Data missing from body");
res
.status(400)
.json({
message: "Required data missing from body"
});
}
};
Thanks for the reply.
This is the file of routes:
var express = require('express');
var router = express.Router();
var ctrlHotels = require('../controllers/hotels.controllers.js');
// Hotel routes
router
.route('/hotels')
.get(ctrlHotels.hotelsGetAll);
router
.route('/hotels/:hotelId')
.get(ctrlHotels.hotelsGetOne);
router
.route('/hotels/new')
.post(ctrlHotels.hotelsAddOne);
module.exports = router;
My console.log() tell:
GET /api/hotels
Requested by: undefined
GET the hotels
{}
(node:2780) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library ins
null
[]
Found hotels 0
I have a hothel-data.json file with all the hotels, the professor in the video at the command prompt when he connects to the db type mongod, but he gave me an error, so when I plug in the db type: mongod --dbpath = data.
I have a main folder, inside I have an API folder with 3 folders inside.
1 CONTROLLERS folder, with hotels-controllers.js, 2 DATA folder with db.js, dbconnection.js, hotel-data.json, hotels.model.js, and 3 ROUTES folder with index.js.
I solved importing the hotel-data.json file, now it's ok, when typing ocalhost: 3000 / api / hotels I see all the hotels.
Thanks anyway.
Aurora
Related
I'm building a mockup website to try and learn NodeJS. I want a login system and I'm trying to connect my register page with my database script. The sql function that sends queries to the database is working as intended, however, when trying to call the query function from the script that manages the register webpage all I get is an error 500.
It would be cool if someone could point me in the right direction, surely it's some quirk from NodeJS I don't know about yet.
Here is my register page script that should call the query function from POST routing:
var express = require('express');
var router = express.Router();
var db = require('../public/javascripts/dbController');
router
.get('/', function(req, res, next) {
res.render('register.html', {title: 'Register'})
})
.post('/', function(req, res, next) {
register(req.body);
res.render('register.html', {title: 'Register'})
})
function register(request)
{
let username = request.login;
let password = request.password;
let sql = "INSERT INTO users (user_username, user_password, user_status) VALUES ('"+username+"','"+password+"', 1);";
console.log("query");
//Why is this not working?
db.query(sql);
}
module.exports = router;
And here is (part of) my dbController script:
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('./public/database/db.db', sqlite3.OPEN_READWRITE, (err) => {
if (err && err.code == "SQLITE_CANTOPEN") {
createDatabase();
return;
} else if (err) {
console.log("Getting error " + err);
exit(1);
}
});
//This function is not running when I ask for it in register.js
function query(sql){
console.log("running query: " + sql)
db.all(sql, [], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.name);
});
});
}
module.exports = query;
I figure that I probably have to route my scripts through the main app script or maybe I'm exporting wrong? Anyway, any nudge in the right direction would be great because I've been stuck on it a few days. Thanks!
For what I can see, you're indeed importing the "query" function into your "register" page. But you're setting a name of "db" to it.
var db = require('../public/javascripts/dbController');
but you're not exporting "db" you're exporting "query":
module.exports = query;
But that's not really the issue, you could just call it "myRandomNameImport" and it would still work. The problem is that you're accessing a property of "db" that does not exist.
db.query(sql); /* <- db.query does not exist.
* Try db(sql) instead. */
"db" does not have any properties called "query", the function you're trying to use is "db".
function register(request) {
let username = request.login;
let password = request.password;
let sql = "INSERT INTO users (user_username, user_password, user_status) VALUES ('"+username+"','"+password+"', 1);";
console.log("query");
db(sql); /*<- Just call db()*/
}
I have many files which are stored in upload_file collection in mongodb and they have relations with related content types. However when I open Strapi CMS UI, I cannot see the file attached on its content type.
I am using Strapi v3.4.6 — Community Edition.
In the first picture is showing the my one of upload_file collection item. Its relation is shown in red circle.
In the second picture is showing the my main content type collection item. You see that its id and upload_file rel id is matching.
But in Strapi UI, this file is not linked to model. The file exists in file system of Strapi. However it is not visible
I can add this file manually, but is there any quick way to do this?
You need to migrate the database. We solved with a basic script.
Run http://localhost:3000/migrate
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017";
var dbName = "YOURDBNAME";
const express = require('express')
const app = express()
const port = 3000
var _db;
var _dbo;
var tables = {
"table1": "TabLE1",
"table2": "TABle2",
}
app.get('/migrate', (req, res) => {
res.send('Started!')
_dbo.collection("upload_file").find({}).toArray(function(err, result) {
if (err) throw err;
result.forEach(function (item) {
if (item.related.length > 0) {
var related = item.related[0];
var query = { '_id': related.ref };
var newvalues = { $set: {} };
newvalues.$set[related.field] = item._id;
var tableName = related.kind.toLowerCase();
_dbo.collection(tables[tableName]).updateOne(query, newvalues, function(err, res) {
if (err) throw err;
console.log(res != null ? res.ops : null);
});
}
})
// db.close();
});
})
MongoClient.connect(url, function(err, db) {
if (err) throw err;
_dbo = db.db(dbName);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
// Run http://localhost:3000/migrate
When uploading your image to strapi make sure your formData has these fields
const formData = new FormData();
formData.append('files', image);
formData.append('ref', 'contentTypeName');
formData.append('refId', dataItemId);
formData.append('field', 'image');
I am working on setting up Stampery. I am unable to figure out where to set the string API key in this API.JS file. The documentation says to set the STAMPERY_TOKEN as the API key not sure how to do this. Any help would be appreciated.
The link for Stampery is https://github.com/stampery/office.
'use strict';
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser')
const Stampery = require('stampery');
const development = process.env.NODE_ENV !== 'production';
const stamperyToken = process.env.STAMPERY_TOKEN;
var proofsDict = {}
if (!stamperyToken) {
console.error('Environment variable STAMPERY_TOKEN must be set before running!');
process.exit(-1);
}
//var stampery = new Stampery(process.env.STAMPERY_TOKEN, development ? 'beta' : false);
// For now, always use production Stampery API due to not making it work against beta.
var stampery = new Stampery(process.env.STAMPERY_TOKEN);
router.use(bodyParser.json());
router.post('/stamp', function (req, res) {
var hash = req.body.hash;
// Throw error 400 if no hash
if (!hash)
return res.status(400).send({error: 'No Hash Specified'});
// Transform hash to upper case (Stampery backend preferes them this way)
hash = hash.toUpperCase()
// Throw error 422 if hash is malformed
var re = /^[A-F0-9]{64}$/;
if (!(re.test(hash)))
return res.status(422).send({error: 'Malformed Hash'});
stampery.stamp(hash, function(err, receipt) {
if (err)
res.status(503).send({error: err});
else
res.send({result: receipt.id, error: null});
});
});
router.get('/proofs/:hash', function (req, res) {
var hash = req.params.hash;
stampery.getByHash(hash, function(err, receipts) {
if (err)
res.status(503).send({error: err});
else
if (receipts.length > 0)
res.send({result: receipts[0], error: null});
else
res.status(200).send({error: 'Oops! This email has not yet been attested by any blockchain.'});
});
});
module.exports = router;
I have added the following in Azure website. Should this suffice :
You need to set up STAMPERY_TOKEN environment veriable before starting your server.
You can do this like this for example (in Windows) set STAMPERY_TOKEN=your-token&& node app.js
There are 2 ways to add this to environment (For Ubuntu).
Add to bashrc File. Like:
export STAMPERY_TOKEN="YOUR-TOKEN"
Pass these params before running server. Like:
STAMPERY_TOKEN=YOUR-TOKEN node server.js
To access this variable you can get by:
console.log(process.env["STAMPERY_TOKEN"]);
The error is triggered in the Product.find statement below:
var bodyparser = require('body-parser');
var express = require('express');
var status = require('http-status');
var _ = require('underscore');
var mongoose = require('mongoose');
var productSchema = require('./product');
var schema = new mongoose.Schema(productSchema);
schema.index({ name: 'text' });
module.exports = function(wagner) {
var api = express.Router();
api.use(bodyparser.json());
api.get('/product/text/:query', wagner.invoke(function(Product) {
return function(req, res) {
console.log("we are in the get " + req.params.query);
Product.
find(
{ $text : { $search : req.params.query } },
{ score : { $meta: 'textScore' } }).
sort({ score: { $meta : 'textScore' } }).
limit(10).
exec(handleMany.bind(null, 'products', res));
};
}));
return api;
};
function handleMany(property, res, error, result) {
console.log("We are handling the many");
if (error) {
console.log(error);
return res.
status(status.INTERNAL_SERVER_ERROR).
json({ error: error.toString() });
}
var json = {};
json[property] = result;
res.json(json);
}
I'm running MongoDB 3.4.2 on windows 10. I explicitly ran the statement db.products.ensureIndex({name: "text"}); in the MongoDB shell and for the first time I didn't get the error. It still gets timeout errors intermittently, though, when the query takes more than 2000 ms. I thought that I didn't have to explicitly add an index in the MongoDB shell because I'm putting on a schema index in the above code, but I don't know for sure.
Thanks,
William
I got into the MongoDB shell and put the index on the products collection like this:
db.products.createIndex({name: "text"})
That was my solution, and it worked, but I don't know if there was a glitch somewhere that made that solution necessary.
I'm using Node.JS + Express.JS + Multer to handle file uploads. The problem is that I need to query the database to see if a file with this name has been uploaded in the past. If it hasn't been uploaded, then it should be accepted. Otherwise, the file should not be accepted. I'm trying to get this to work using the onFileUploadStart function; however, the database query is asynchronous and I see no way to return false given that the result of the query appears in a callback. If there is a way to execute the query synchronously, my goal will be easy to accomplish. Here is the code:
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var connection = mysql.createConnection({
//connection details
});
router.post('/upload', multer({
onFileUploadStart: function(file, req, res) {
var queryString = "SELECT count(fileName) as count FROM table WHERE fileName = ?;",
queryInserts = [file.originalname];
queryString = mysql.format(queryString, queryInserts);
connection.query(queryString, function(err, rows) {
if (err) {
// handle error
} else {
if (rows[0].count > 0) {
// file should not be accepted
} else {
// file should be accepted
}
}
});
},
dest: "./uploads/"
}), function(req, res) {
// do other stuff
});
Any ideas of how I can accomplish this will be greatly appreciated. Thanks.
My quick reaction would be to use promises. You could have your onFileUploadStart handler create a deferred, assign its promise to the active request object and handle the resolution or rejection of the promise. Then in the main handler for the upload route, you could use then.
I believe this would basically be the new code as applied to your current code. I Note that I am using the Q promises library, but there are other options (promises are also built into ES6 if you are using it).
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var Q = requires('q');
var connection = mysql.createConnection({
//connection details
});
router.post('/upload', multer({
onFileUploadStart: function(file, req, res) {
var deferred = Q.defer();
req.fileUploadPromise = deferred.promise;
var queryString = "SELECT count(fileName) as count FROM table WHERE fileName = ?;",
queryInserts = [file.originalname];
queryString = mysql.format(queryString, queryInserts);
connection.query(queryString, function(err, rows) {
if (err) {
// handle error
deferred.reject('You had an error...');
} else {
if (rows[0].count > 0) {
// file should not be accepted
deferred.reject('You had a duplicate file');
} else {
deferred.resolve(file); // ?? or something useful
// file should be accepted
}
}
});
},
dest: "./uploads/"
}), function(req, res) {
req.fileUploadPromise
.then(function(successResult){
// do other stuff
res.status(200).send('success');
})
.catch(function(errorResult){
// read the error result to provide correct code & error message for user
})
.done();
});