Express response is not defined when using separate callback - node.js

Just an elementary question.
The following code return tasks successfully:
const mongojs = require('mongojs');
const db = mongojs('localhost:27017/tasks', ['tasks']);
router.get('/tasks', function(req, res, next) {
db.tasks.find(function(err, tasks) {
if (err) {
res.send(err);
}
if (tasks) {
res.json(tasks);
}
});
});
But, when I split it and call it as callback, it returns: References: tasks is not defined.
Repository.js:
const mongojs = require('mongojs');
const db = mongojs('localhost:27017/tasks', ['tasks']);
module.exports = {
ReadAllTasks(callback) {
db.tasks.find(function(err, tasks) {
if (err) {
callback(err, null);
}
callback(null, tasks);
});
}
}
Route.js:
const express = require('express');
const router = express.Router();
const repository = require('./repository');
router.get('/tasks', function(req, res, next) {
repository.ReadAllTasks(function(err, tasks) {
if (err) {
res.send(err);
}
if (tasks) {
res.json(tasks);
}
})
});
module.exports = router;
Anyone know to fix it?

try this, because you are not returning the valid object.
module.exports = {
ReadAllTasks: (callback)=>{
db.tasks.find(function(err, tasks) {
if (err) {
callback(err, null);
}
callback(null, tasks);
});
}
}

Related

MongoDB & Mongoose, Save Nested Array of Objects - Node.js

I'm trying to save a nested array of objects to my MongoDB collection but the app is only saving the first object in the nested BankAccountsArray, I've tried using the .markModified() method but haven't got any success. I've attached the data accepted from the frontend part + my model schema + the route, Thanks for the help!
Frontend Data Accepted:
{
companyHoldingPercentage: '10%',
BankAccountsArray: [
{
bankAccountNumber: '32',
bankBranchNumber: '55',
bankName: 'abc'
},
{
bankAccountNumber: '3123',
bankBranchNumber: '412',
bankName: 'cde'
}
]
}
Model:
const mongoose = require("mongoose");
const BankAccountsArraySchema = mongoose.Schema({
bankName: String ,
bankBranchNumber: String ,
bankAccountNumber: String
}
);
const BankAccountsIndexSchema = mongoose.Schema({
companyHoldingPercentage: String ,
BankAccountsArray: [BankAccountsArraySchema]
});
module.exports = mongoose.model(
"bank-accounts-object",
BankAccountsIndexSchema
);
Route:
var express = require("express");
var router = express.Router();
const BankAccountsIndexModel = require("../Models/BankAccountsIndexModel");
router
.route("/BankAccountsIndexRoute")
.get(async (req, res, next) => {
BankAccountsIndexModel.find((err, collection) => {
if (err) {
console.log(err);
} else {
res.json(collection);
}
});
})
.post(async (req, res, next) => {
console.log(req.body);
const {
companyHoldingPercentage,
BankAccountsArray: [{ bankName, bankBranchNumber, bankAccountNumber }],
} = req.body;
try {
const NewBankAccountsIndexModel = new BankAccountsIndexModel({
companyHoldingPercentage,
BankAccountsArray: [{ bankName, bankBranchNumber, bankAccountNumber }],
});
NewBankAccountsIndexModel.markModified(req.body.BankAccountsArray);
NewBankAccountsIndexModel.save();
// res.json(bankAccount);
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
})
module.exports = router;
Can you try to refactor your .post() endpoint like this:
.post(async (req, res, next) => {
try {
let new_bank_account = await BankAccountsIndexModel.create(req.body);
res.status(200).json(new_bank_account);
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
})

Posting Json to server in android using volley but getting only id in the server

I am using mongodb and node.js to build up a rest Api btw i am a beginner....So i fired up my localhost3000 using express but when i posted in android it gives only id and not the content..
like
[{"_id":"59f4bb537ddb610f0c94fcd0","__v":0},
{"_id":"59f4bca47ddb610f0c94fcd1","__v":0},
{"_id":"59f4c5ce7ddb610f0c94fcd2","__v":0}
]
Its giving only the ids in localhost:3000/api/vehicles
My android mainActivity
String url = "http://10.0.2.2:3000/api/vehicles";
try{
JSONObject jsonObject=new JSONObject();
jsonObject.put("UserName" , "zaid");
jsonObject.put("Password" , "passwords");
final String mRequestBody = jsonObject.toString();
JsonObjectRequest jor = new JsonObjectRequest(Request.Method.POST, url,
jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println(response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() {
try{
return mRequestBody == null ? null :
mRequestBody.getBytes("utf-8");
}catch (UnsupportedEncodingException e){
return null;
}
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
if(response.statusCode == 200){
}
return super.parseNetworkResponse(response);
}
};
Volley.newRequestQueue(this).add(jor);
}
catch (JSONException e){
}
The node.js
var mongoose = require('mongoose');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
Vehicle = require('./app/models/vehicle')
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
mongoose.connect('mongodb://localhost:27017/codealong');
var port = 3005;
var router = express.Router();
app.use('/api', router);
router.use(function(req, res, next) {
// body...
console.log('Processing......');
next();
});
router.get('/', function(req, res) {
res.send('HELOOOOO ' + 'World');
// body...
});
router.route('/vehicles')
.post(function(req, res) {
// body...
var vehicle = new Vehicle();
vehicle.make = req.body.make;
vehicle.model = req.body.model;
vehicle.color = req.body.color;
vehicle.save(function(err) {
if (err) {
res.send(err);
};
res.json({ message: 'Vehicle as manufactured' });
// body...
});
})
.get(function(req, res) {
Vehicle.find(function(err, vehicles) {
if (err) {
res.send(err);
}
res.json(vehicles);
// body...
});
// body...
});
router.route('/vehicles/:id')
.get(function(req, res) {
Vehicle.findById(req.params.id, function(err, vehicles) {
if (err) {
res.send(err);
}
res.send(vehicles);
// body...
}); // body...
});
.delete(function(req, res) {
// body...
var id = req.params.id;
Vehicle.removeV(id, function(err, vehicle) {
if (err) {
throw err;
}
res.json(vehicle);
// body...
});
})
.put(function(req, res) {
var id = req.params.id;
var veh = req.body;
Vehicle.updateV(id, veh, {}, function(err, vehicles) {
res.json(vehicles);
// body...
});
// body...
});
router.route('/vehicles/make/:make')
.get(function(req, res) {
var query = { make: req.params.make };
Vehicle.find(query, function(err, vehicles) {
if (err) {
res.send(err);
}
res.json(vehicles);
// body...
});
// body...
});
///fire up //////////
app.listen(port);
console.log('server started');
So i need this is the app.js file which i edited in js

Nodejs 8 - How to use Async/Await with mongoose

im running nodejs version v8.5.0 using nvm.
I have a simple index function which returns all the users in my mongo db using mongoose.
User.find({}, (err, results) => {
if (err) {
return res.json(err);
}
return res.json(results);
});
I'm trying to convert the traditional call back approach to the new async and await.
user.controller.js
'use strict';
const User = require('../models/user.model');
class UserController {
constructor() {
}
async index(req, res) {
try {
let result = await User.find({});
return res(result);
} catch (e) {
return res.json(e);
}
}
show(req, res) {
}
update(req, res) {
}
store(req, res) {
}
destroy(req, res) {
}
}
module.exports = UserController;
user.route.js
'use strict';
let express = require('express');
let router = express.Router();
let controller = require('../controllers/user.controller');
controller = new controller();
router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.store);
router.put('/:id', controller.update);
router.delete('/:id', controller.destroy);
module.exports = router;
However when i run this, i get an empty object back.
The empty object is the error (calling res.json(javascript_error) will return an empty object).
Instead of
return res(result);
use
res.send(result)

Mongoose .save is not a function

JS:
var express = require('express');
var router = express.Router();
// Mongoose
var mongoose = require('mongoose');
var mongoosedb = 'DBURL';
mongoose.connect(mongoosedb);
var database = mongoose.connection;
database.on('error', console.error.bind(console, 'connection error:'));
database.once('open', function() {
console.log('Mongoose is connected.');
});
var taskSchema = mongoose.Schema({
name: String,
isDone: Boolean
});
var Tasks = mongoose.model('Tasks', taskSchema);
// Get all tasks
router.get('/tasks', function(req, res, next) {
Tasks.find(function(err, tasks) {
if(err) {
console.log('error');
res.send(err);
}
res.json(tasks);
});
});
// Get single task
router.get('/task/:id', function(req, res, next) {
Tasks.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, task) {
if(err) {
res.send(err);
}
res.json(task);
});
});
// Save task
router.post('/task', function(req, res, next) {
var task = req.body;
if(!task.title || !(task.isDone + '')) {
res.status(400);
res.json({
"error": "Bad Data"
});
} else {
task.save(function(err, task) {
if(err) {
res.send(err);
}
res.json(task);
})
}
});
// Delete task
router.delete('/task/:id', function(req, res, next) {
Tasks.remove({_id: mongojs.ObjectId(req.params.id)}, function(err, task) {
if(err) {
res.send(err);
}
res.json(task);
});
});
// Update task
router.put('/task/:id', function(req, res, next) {
var task = req.body;
var updTask = {};
if (task.isDone) {
updTask.isDone = task.isDone;
}
if (task.title) {
updTask.title = task.title;
}
if (!updTask) {
res.status(400);
res.json({
"error": "Bad Data"
});
} else {
task.update({_id: mongojs.ObjectId(req.params.id)}, updTask, {}, function(err, task) {
if(err) {
res.send(err);
}
res.json(task);
});
}
});
module.exports = router;
I'm simply just trying to add a record to MongoDB using Mongoose.
After some Googling I couldn't find answer. My .find and .findOne methods work fine but for some reason I get the error task.save is not a function. What am I doing wrong?
I think your task creation is being done incorrectly.
First go ahead and import your model up at the top with your dependencies so we can access the model methods directly:
var express = require('express');
var router = express.Router();
// Mongoose
var mongoose = require('mongoose');
var mongoosedb = 'DBURL';
var Task = require('mongoose').model('Task'); // add your Task model
Then, in your save a task code, change it to this:
// Save task
router.post('/task', function(req, res, next) {
var task = new Task(req.body) // See http://mongoosejs.com homepage demo example for basic creation
if(!task.title || !(task.isDone + '')) {
res.status(400);
res.json({
"error": "Bad Data"
});
} else {
task.save(function(err, task) {
if(err) {
res.send(err);
}
res.json(task);
})
}
});
As your current Task creation is setup, you're just setting it to the req.body contents but not actually initializing an instance via the mongoose methods.
I personally like to use mongoose promises instead, just because I tend to like the style more. But you could also do something like this, if you have given access to your Task model via grabbing it as a dependency (as shown above):
Task.create(req.body)
.then(function(newTask) {
console.log("Task created successfully.");
return res.json(newTask); // using res.json here
})
.catch(function(err) {
console.log("There was a problem creating task.");
return res.status(500).json(err); // sends status with json obj
})
Anyhow, I hope this helps, let me know if this works, if not I'll check back later and see!
Your variable task is the body object you have defined previously :
var task = req.body;
If you want to generate a Tasks document from it, use :
var newTask = new Tasks(task);
newTask.save(function(err, task) {
if (err) {
res.send(err);
}
res.json(task);
});
Check mongoose Models documentation
You have also confused task.update with Tasks.update

How to reuse database controllers

I'm trying to reuse my controllers which handle database operations. I'm bit struggling with structuring my application. Here's what I have:
server.js
var apiController = require('./controllers/api');
router.get('/cars', function (req, res) {
// get all cars from DB and render view
apiController.getCars().then(function (cars) {
res.render('index', {cars: cars});
});
});
router.get('/api/cars', function (req, res) {
// get all cars from DB and return JSON
apiController.getCars().then(function (cars) {
res.json(cars);
});
});
controllers/api.js
module.exports = {
getCars: function () {
db.collection('cars').find().toArray( function (err, cars) {
if (err) throw err;
return cars;
});
},
// tried also something like this but this doesn't really work
// for my use case because I don't want to attach any particular
// res to the function
getCars: function (req, res, next) {
db.collection('cars').find().toArray( function (err, cars) {
if (err) throw err;
res.json(cars);
});
},
};
Your current problem is that you expect promises as return in server.js while you use callbacks in the controller. I suggest you change your function getCars to return a Promise. Don't know what ODM/ORM you're using but it might look like something like this:
getCars: function () {
return db.collection('cars').find();
},
server.js
var apiController = require('./controllers/api');
router.get('/cars', function (req, res) {
apiController.get('cars').then(function (cars) {
res.render('index', {cars: cars});
});
});
router.get('/api/cars', function (req, res) {
apiController.get('cars').then(function (cars) {
res.json(cars);
});
});
controllers/api.js
var Promise = require('bluebird');
module.exports = {
get: function (modelName) {
return new Promise(function(resolve,reject){
return db.collection(modelName).find().toArray(function(err, models){
if (err) {
return reject(err);
}
else {
return resolve(models);
}
});
});
}
};
server.js
var apiController = require('./controllers/api');
router.get('/cars', apiController.getCars);
controllers/api.js
function getCarsAsync(req, res, next){
db.collection('cars').find().then(function(carsData){
if(carsData){
return res.send(carsData);
}
else{
return res.status(401).send('User is not authorized');
}
}).catch(function(err){
return next(err);
});
}
module.exports = {
getCars: getCarsAsync
};

Resources