NodeJS retrieve JSON and serve to EJS template - json

my purpose is to get a JSON and serve it to an EJS file.
This is my code:
//server.js
users = require('./controllers/users.js');
global.app_root = path.resolve(__dirname);
app.get('/users', function(req, res) {
res.render('partials/users', {
data: users.retrieve_users
});
})
//users.js
var fs = require("fs");
exports.retrieve_users = function (req, res) {
fs.readFile(app_root + "/config/" + "users-list.json", 'utf8', function (err, data) {
res.end(data);
});
}
//users.ejs
<body>
<%= data %>
</body>
But as output of this code inside the body I see literally this string:
'function (req, res) {
fs.readFile(app_root + "/config/" + "users-list.json", 'utf8', function (err, data) {
res.end(data);
});
}'

The problem is that your data is coming asynchronous and you don't wait for them before the rendering. In fact right now you dont even run the users.retrieve_users function, you just getting back the function declaration and express renders it as string! Change your code to this.
//server.js
users = require('./controllers/users.js');
global.app_root = path.resolve(__dirname);
app.get('/users', function(req, res) {
//a method that get thr user-list data and renders it
users.retrieve_users()
.then(function(users){
res.render('partials/users', {
data: users
});
})
.catch(function(err){
res.status(500).send({ error: 'something blew up' });
})
})
//users.js
var fs = require("fs");
exports.retrieve_users = function () {
//function that returns user-list in promise
return new Promise(function(resolve,reject){
fs.readFile(app_root + "/config/" + "users-list.json", 'utf8', function (err, data) {
if(err) return reject(err)
resolve(data);
});
})
}
//users.ejs
<body>
<%= data %>
</body>

Related

TypeError: Cannot read properties of undefined (reading 'filename') in multer

I have a very similar problem with respect to this fellow community contributor. How do i produce multer error message in my postman I followed through the comments made by other users and it was successful! However, when i tried to post a image that is a jpg formatted image( which i managed to do before the editing), it now fails and state that TypeError: Cannot read property 'filename' of undefined.
// multer.js file
successfully setup multer
**please tell me why this error comes on my code and give me a solution**
const multer = require('multer');
const storage = multer.diskStorage({
fileSize: 1024*1024*2,
destination: function (req, file, cb) {
cb(null, './uploads')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix)
}
})
const filter = function (req, file, cb) {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(new Error('unsupported files'), false)
}
}
var upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter : filter
});
module.exports = upload;
//controller.js file
//create function
here's my logic to create a new user
exports.create = (req, res, next) => {
if (!req.body) {
res.status(400).send({ message: "content cannot be empty !!" })
return
}
let data = { name: req.body.name, description: req.body.description, brand_url:
req.body.brand_url, image_file: req.body.file.filename }; getting error here
let sql = "INSERT INTO influencer SET ?";
db.query(sql, data, (err, results) => {
if (err) throw err;
console.log('data inserted succesfully')
res.redirect('/admin');
});
}
//api.js file
//post API
router.post('/api/create', upload.single('image') ,controller.create) //when I am
sending file its throw back error undefined filename
Please make sure you have added enctype="multipart/form-data"
<form action="/api/create" enctype="multipart/form-data" method="post">
I have tested the codes & found the problem.
exports.create = (req, res, next) => {
if (!req.body) {
res.status(400).send({ message: "content cannot be empty !!" })
return
}
let data = {
name: req.body.name,
description: req.body.description,
brand_url: req.body.brand_url,
image_file: req.file.filename
}; // Remove "body", I have tested, it works well.
let sql = "INSERT INTO influencer SET ?";
db.query(sql, data, (err, results) => {
if (err) throw err;
console.log('data inserted succesfully')
res.redirect('/admin');
});
}

Render JSON data onto ejs view with Expressjs

I am trying to get 2 values from a JSON file on to the webpage.
obj["fruit"] and obj["thyroid"]. I use ejs as the template view engine and expressjs.
The below method says "fruit" and "thyroid" are undefined. The console.log works though.
app.post('/top', function (req, res) {
var obj;
fs.readFile('./object.json', 'utf8', function (err, data) {
if (err) throw err;
obj = JSON.parse(data);
console.log(obj["fruit"]);
console.log(obj["thyroid"]);
});
res.render(
'disp.ejs',
{
food: obj["fruit"]
name: obj["thyroid"]
}); // render
});
fs.readFile(path[, options], callback) is the asynchronous way to read a file. The way your code is setup node will start reading the file and immediately then call res.render before the file data is finished reading.
If you put the res.render inside the callback it will only be called when the file is finished reading and the data variable has what you need.
for example:
app.post('/top', function (req, res) {
var obj;
fs.readFile('./object.json', 'utf8', function (err, data) {
if (err) throw err;
obj = JSON.parse(data);
console.log(obj["fruit"]);
console.log(obj["thyroid"]);
res.render(
'disp.ejs',
{
food: obj["fruit"]
name: obj["thyroid"]
}); // render
});
});

I can't get my get request to work

i can't get my get request to work, im using angular and im new to it and using it because my project dictates i must use it, im trying to get my entry from my mongodb batabase, im also running an expressjs server ill attach all the code i can please tell me of my mistakes i'm sure there are plenty.
//factory
app.factory('whipmeet', ['$http', function($http) {
return $http.get('http://mongodb://127.0.0.1:27017/finalwhipmeet')
.success(function(data) {
return JSON.parse(data);
})
.error(function(err) {
return err;
});
}]);
//controller
app.controller('MainController', ['$scope', 'whipmeet', function($scope, whipmeet) {
whipmeet.success(function(data) {
$scope.meetinfo = data,
$scope.meetlikes = 23;
});
}]);
//index.html(only view)
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
</head>
<body ng-app="WhipMeetApp">
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<h1 id="test1"> teting </h1>
<div class="main" ng-controller="MainController">
<div class="container">
<div class="card" ng-repeat="meet in meets">
<meet-info info="likes"></meet-info>
</div>
</div>
</div>
<!-- modules -->
<script src="/javascripts/app.js"></script>
<!-- controllers -->
<script src="/javascripts/controllers/MainController.js"></script>
<!-- services -->
<script src="/javascripts/services/whipmeet.js"></script>
<!-- directives -->
<script src="/javascripts/directives/meetInfo.js"></script>
</body>
</html>
//schema im trying to pull
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MeetSchema = new Schema ({
name: String,
location: String,
car: String,
date: Date,
time: Number,
type: String,
stock: Boolean
});
module.exports = mongoose.model('Meet', MeetSchema);
//error i get in console
angular.js:9734 GET http://mongodb//127.0.0.1:27017/finalwhipmeet net::ERR_NAME_NOT_RESOLVED
​
please tell me if i need to post any more files/code for this to be clear, i am really sorry this may be out of format but im a beginner and i'm trying my best to set this up through tutorials and codeacademy, i just need to be able to display my data and how to create a post in the same format.
i greatly appreciate the help of anyone who wants to help, please don't be harsh on a noob.
//meets.js route
var express = require('express');
var router = express.Router();
var Meet = require('../models/Meet.js');
/* GET /meets listing. */
router.get('/', function(req, res, next) {
Meet.find(function (err, meets) {
if (err) return next(err);
res.json(meets);
});
});
/* POST /meets */
router.post('/', function(req, res, next) {
Meet.create(req.body, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* GET /meets/id */
router.get('/:id', function(req, res, next) {
Meet.findById(req.params.id, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* PUT /meets/:id */
router.put('/:id', function(req, res, next) {
Meet.findByIdAndUpdate(req.params.id, req.body, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* DELETE /meets/:id */
router.delete('/:id', function(req, res, next) {
Meet.findByIdAndRemove(req.params.id, req.body, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
module.exports = router;
The example uses callback success and error functions. You can use promises as well.
The angular factory calls express routes, which connects with mongoDB for create, update, delete or get operation and sends the response back to factory. Which passes the result/error to controller.
app.controller('MainController', ['$scope', 'whipmeet', function($scope, whipmeet) {
//get all
whipmeet.getWhipmeet(function(data){
$scope.meetinfo = data;
},
function(err){
console.log(err)
});
//get one
whipmeet.getWhipmeet("id::1234567", function(data){
},
function(err){
console.log(err)
});
//create
whipmeet.createWhipmeet({key: "some value"}, function(data){
},
function(err){
console.log(err)
});
}]);
app.factory('whipmeet', ['$http', function($http) {
return {
createWhipmeet: function (obj, success, error) {
$http.post('/meets/', obj, {}).
then(function (data) {
success(data)
}, function (e) {
error(e);
});
},
getWhipmeets: function (success, error) {
$http.get('/meets/').
then(function (data) {
success(data)
}, function (e) {
error(e);
});
},
getWhipmeet: function (id, success, error) {
$http.get('/meets/'+id).
then(function (data) {
success(data)
}, function (e) {
error(e);
});
}
}
}]);

show json data in index file

I dont understand why I cant display my json data. I am new to javascript and I want to display the data in the json file to my index file.
I have used the express generator for all the files. I did read that I should add this FS code in my app.js, but I cant use the data variable in my index file in my view. Any help ?
var express = require('express');
var router = express.Router();
var fs = require('fs');
/* GET home page. */
router.get('/', function(req, res, next) {
var file = __dirname + '/public/list/list.json';
var data;
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
data = JSON.parse(data);
console.log(data);
});
res.render('index', { title: data });
console.log(data);
});
module.exports = router;
here is my json file
{
"username":"xyz",
"password":"xyz#123",
"email":"xyz#xyz.com",
"uid": 1100
}
fs.readFile is asynchronous , so you should put res.render(..) inside his callback , because it will fired when the readFile function ends. So change your code to :
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
data = JSON.parse(data);
console.log(data);
res.render('index', { title: data });
});
The above answer is correct, but there's also an alternative.
If you're using this file for your index page, it'd be used a lot. If the data isn't changing, you can simply require the JSON file at the top of your code and return it in the request.
var express = require('express');
var router = express.Router();
var list = require(__dirname + '/public/list/list.json');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: list });
});
module.exports = router;
However, if that data does change frequently, reading the file is the way to go.

NodeJS: saving JSON to MongoDB

I am trying to get JSON from an API and store it into a MongoDB database.
Obviously, it doesn't work. My app seems to hang around the point where I try to save the data to the database. Please advise what to do.
Here's my code:
var express = require('express');
var router = express.Router();
var http = require('http');
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/zak", {native_parser : true});
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
var site = 'http://www.vsechnyzakazky.cz/api/v1/zakazka/?format=json&limit=2';
function getData(cb) {
http.get(site, function(res) {
// explicitly treat incoming data as utf8 (avoids issues with multi-byte chars)
res.setEncoding('utf8');
// incrementally capture the incoming response body
var body = '';
res.on('data', function(d) {
body += d;
});
// do whatever we want with the response once it's done
res.on('end', function() {
try {
var parsed = JSON.parse(body);
} catch (err) {
console.error('Unable to parse response as JSON', err);
return cb(err);
}
// pass the relevant data back to the callback
cb(
parsed.objects
);
});
}).on('error', function(err) {
// handle errors with the request itself
console.error('Error with the request:', err.message);
cb(err);
});
}
function writeData (data, allGood){
// couple of visual checks if all looking good before writing to db
console.log('writing');
console.log(typeof data);
console.log(data);
db.collection('zakazky').save(data, function(error, record){
if (error) throw error;
console.log("data saved");
});
}
function allGood(){console.log('all done');}
getData(writeData);
// ---------------------
module.exports = router;
You are calling the save() instead of insert(). Change this part and it will work:
// this should call insert, not save
db.collection('zakazky').insert(data, function(error, record){
if (error) throw error;
console.log("data saved");
});