Retrieve an object from collection by its name using nodejs - angularjs

so Im currently making an application using MEAN stack. The problem i have at the moment is, when making a call to the API, I am able to successfully retrieve all objects and each object by ID from the database(using POSTMAN(Chrome)) I have set up using mongoose & express router. My question is, can I retrieve an object by it's name ? I have been searching the web and I am unsure how I could implement this. For example: This is the Api code i currently have.
var Dishes = require('../../app/models/dishes');
var Terms = require('../../app/models/terms');
var config = require('../../config');
module.exports = function(app,express){
// api ---------------------------------------------------------------------
var apiRouter = express.Router();
// middleware to use for all requests
apiRouter.use(function (req, res, next) {
// do logging
console.log('Somebody just came to our app!');
next();
});
// Test routes to make sure everything is working
//(accessed at GET http://localhost:3000/api)
apiRouter.get('/', function (req, res) {
res.json({message: 'Welcome to the API!'});
});
/** ================================= Dishes ==========================================**/
//on routes that end in /dishes , show all dishes in json
apiRouter.get('/dishes', function (req, res) {
Dishes.find(function (err, dishes) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
res.send(err);
res.json(dishes); // return all dishes in JSON format
});
});
//on routes that end in /dishes/:_id , show all the this with the corresponding ID
// get the dish with that id
// (accessed at GET http://localhost:8080/api/dishes/:dish_id)
apiRouter.get('/dishes/:_id',function(req, res) {
Dishes.findById(req.params._id, function(err, dish) {
if (err) res.send(err);
// return that dish
res.json(dish);
});
});
return apiRouter;
};
The dish model I am access is as follows:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//with Mongoose everything is derived from a schema ! Lets get a reference and define our Dishes Schema
var DishSchema = mongoose.Schema({
dishName: {type: String, index: {unique: true}},
Desc : {type: String, index: { unique: true}},
Allergy: String,
HealthRisks: String
},{collection:'Dishes'});
module.exports = DishSchema;
//The Next step is to compile our schema into a model
var Dishes = mongoose.model('Dishes', DishSchema);//Dish Schema into model
// return the model
module.exports = mongoose.model('Dishes', DishSchema)
What I wish to do is make an api call to (/dishes/:dishName) and return the relevant dish. Any help would be greatly appreciated.

apiRouter.get('/dishes/getByName/:dishName',function(req, res) {
Dishes.findOne({dishName:req.params.dishName}, function(err, dish) {
if (err) res.send(err);
// return that dish
res.send(dish);
});
});

Related

MongooseJS Update API

I am having a 404 issue with my NodeJS API. I don't know if I am quite doing it right, I tried referring to documentation, and I feel like it's close.
MongoDB Schema
var User = mongoose.Schema({
local: {
email: String,
password: String,
handle: String,
pic: {data: Buffer, contentType: String}
}
});
NodeJS UPDATE API
app.post('/api/users', function(req, res, user) {
User.update({email : user.email,
password : user.password,
handle : user.handle,
pic : user.pic},
{$set: {
email : req.body.email,
password : req.body.email,
handle : req.body.handle,
pic : req.body.pic,
done : false
}
}, function(err, users) {
if(err) {
res.send(err);
}
res.redirect('/profile');
});
});
Controller POST API call
$scope.editProfile = function() {
$http.post('/api/users', $scope.editFormData)
.success(function(data) {
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
Any suggestions?
You are not doing a post call correct. You can't pass your post object in the URL. Your node post should look like this.
app.post('/api', upload.array(), function(req, res) {
var body = req.body; //body will be your post object
});
For a post to work you need to make sure you have the proper things added to your Node Project. The above example is using ExpressJS with require('body-parser') and require('multer'). The example you are showing will never show as a true path. For reference here is how you would do a get in node.
app.get('/getcall/*', function(){
// the * denotes any singleton parameter you wanted to pass in.
})
Here are the references I use in all my node projects. These are the basics.
var express = require('express'),
bodyParser = require('body-parser'),
multer = require('multer'),
helmet = require('helmet'),
upload = multer(),
path = require('path'),
request = require('request'),
app = express(),
http = require('http');
Also as for your angular call an $http.post looks like this and you should be using .then instead of .success.
$http.post('/api', $scope.editFormData)
.then(function successCallback(resp) {
console.log(resp.data)
}, function errorCallback(resp) {
console.log(resp)
});

MEAN Stack Application throws "TypeError: Cannot read property 'save' of undefined"

I'm new to MEAN so I try to be as precise as possible with this. I followed a tutorial step by step for a small MEAN Stack application. Everything works fine so far except of editing and saving when viewing in AngularJS (tested PUT and DELTE with Restful client and it works fine).
According to the error message I receive, the error seems to lay in one of my Controllers with the save function.
The error I receive is
TypeError: Cannot read property 'save' of undefined
at /Users/xxx/WebstormProjects/cms/controllers/surveysController.js:29:15
Bellow is my controller
require('../models/survey');
var mongoose = require('mongoose');
var _ = require('underscore');
var Survey = mongoose.model("Survey");
exports.post = function(req, res){
var survey = new Survey(req.body);
survey.save();
res.jsonp(survey);
};
exports.get = function(req, res){
Survey.find().exec(function(err, surveys) {
res.jsonp(surveys);
});
};
exports.show = function(req, res){
Survey.load(req.params.surveysId, function(err, survey){
res.jsonp(survey);
});
};
exports.put = function(req, res){
Survey.load(req.params.surveysId, function(err, survey){
survey = _.extend(survey, req.body);
survey.save(function(err){
res.jsonp(survey);
});
});
};
exports.delete = function(req, res){
Survey.load(req.params.surveysId, function(err, survey){
survey.remove(function(err){
res.jsonp(survey);
});
});
};
There seems to be a problem with the section bellow, to be on point with ".save(function(err)". I followed the tutorial step by step and I can't figure what the problem is here. As mentioned before, it works fine in RESTClient.
exports.put = function(req, res){
Survey.load(req.params.surveysId, function(err, survey){
survey = _.extend(survey, req.body);
survey.save(function(err){
res.jsonp(survey);
});
});
};
As Requested the Schema bellow
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SurveySchema = new Schema({
created: {
type: Date,
default: Date.now
},
von: Date,
titel: String,
beschreibung: String
});
SurveySchema.statics = {
load: function(id, cb){
this.findOne({_id : id}).exec(cb);
}
};
mongoose.model('Survey', SurveySchema);

NodeJS - Cannot set headers after they are sent - Multiple Calls

I'm trying to write an app that find a city in a MongoDB collection and uses the latitude and longitude it returns to find all zip codes within a certain distance. It seems to work, but the problem is that I'm getting an error that I can't set headers after they've already been sent. However, I've separated the to routes into different requests I don't understand why I'm still getting this error. What is the best way to make multiple calls to the API?
Here is my router in Node/Express:
// route to get city
app.get('/cities/:zip', function(req, res) {
// use mongoose to get the city in the database
console.log(req.params.zip);
var query = City.find({"zip" : req.params.zip});
query.exec(function(err, city) {
if (err)
res.send(err);
res.json(city);
});
});
// route to find cities within 50 miles
app.get('/matches/:latMin/:latMax/:lonMin/:lonMax', function(req, res) {
console.log(req.params.latMin + req.params.latMax + req.params.lonMin + req.params.lonMax);
var matches = City.find({latitude: {$gt: req.param.latMin, $lt:req.params.latMax }, longitude : {$gt :req.param.lonMin, $lt : req.param.lonMax}});
matches.exec(function(err, match){
if(err)
res.send(err);
console.log(match);
res.json(match);
});
});
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html'); // load our public/index.html file
});
Here is my Angular Controller
$scope.update = function (zip) {
City.get({zip : zip}).success(function(response){
$scope.weather = response
}).then(function(response){
$scope.weather = response.data;
})
if(zip.length = 5){
$http.jsonp('http://api.openweathermap.org/data/2.5/weather?zip='+ zip +',us&callback=JSON_CALLBACK&units=imperial').success(function(data){
$scope.data=data;
});
var box = getBoundingBox([$scope.weather[0].latitude, $scope.weather[0].longitude], 50);
City.matches(box[1], box[3], box[0], box[2]).success(function(response){
$scope.matches = response
}).then(function(response){
$scope.matches = response.data;
console.log($scope.matches);
})
}
res.send does not return; the call continues to res.json. And please use braces. Please. Maybe they don't look cool or whatever. Just use them.
if (err) { handleError(res, err); return; }
res.status(200).json(city);
Further down, keeping things DRY:
function handleError(res, err) {
res.status(500).json(err);
}

POST and GET images to/out of MongoDB in Angular

I´m making an angular application, which gives users the possibilities, to manage their projects. I´ve got nodeJS & express serveside and MongoDB as my database.
I want to achieve, that a user can upload media(images under 16MB, so no need to use GridFS) to their projects and that you can display which project, has which media attached.
I´m not getting the images, nor an error. How can I pass the project_Id from angular, to my route, to find the media attached to the project? Is this way of trying to POST and GET the media the right way?
The model for projects and for media:
var mediaSchema = mongoose.Schema({
media : {data: Buffer, contentType: String},
project_id : String,
updated_at : {type: Date, default: Date.now }
});
var projectSchema = mongoose.Schema({
author : String,
name : String,
description : String,
tags : String,
updated_at : {type: Date, default: Date.now },
active : {type: Boolean, default: false}
});
The routing
var Media = require('./models/media.js');
//GET all the media
app.get('/uploads/', function(req, res, next){
Media.find(function (err, media){
if (err) return next (err);
res.json(media);
});
});
//GET one item
app.get('/uploads/media/:projectId', function(req, res, next){
Media.findOne(req.params , function (err, media){
if (err) return next (err);
res.json(media);
});
});
Managing the uploads
app.use(multer({ dest: './uploads/',
rename: function (fieldname, filename) {
return filename+Date.now();
},
onFileUploadStart: function (file) {
console.log(file.originalname + ' is starting ...')
},
onFileUploadComplete: function (file) {
console.log(file.fieldname + ' uploaded to ' + file.path)
done=true;
}
}));
var Media = require('./app/models/media.js');
//POST media to the upload directory
app.post('/uploads/', function(req, res){
if(done==true){
Media.create(req.body, function(err, post){
console.log(req.files);
res.end('File uploaded');
});
}
});
Angular Controller
var app = angular.module('myApp', []);
app.controller('projectCtrl', function($scope, $http) {
$scope.myVar = false;
$scope.toggle = function() {
$scope.myVar = !$scope.myVar
};
$http.get('/profile/project/').then(function (res){
$scope.projects = res.data;
});
//GET Media
var projectId = {{projects._id}};
$http.get('/uploads/media' + projectId).succes(function(data){
console.log('Medien-Daten erhalten');
$scope.media = data;
});
});
Kind regards from Germany,
David
Update (new Errors)
Trying to implement a solution, I get problems with my scopes. When I´m adding the $http.get for the media, my other scope seem to fetch no data... they are shown like this:
Update 2(scope error fixed)
Fixed the error in the controller. I hadn´t defined a var for projectId, that caused the error.
Managed to make the GET request work, and my application is looking for entries in the database. But i can´t manage to see any..
Your use of .find is incorrect in the get all function.
See http://mongoosejs.com/docs/api.html#query_Query-find
Media.find({}, function (err, media){
if (err) return next (err);
res.json(media);
});
This will return all documents.

Updating database with node.js and angular

I have an app which posts, gets and deletes data and I would like to add 'update' functionality as well but I can't figure it out..
I have a node.js server which has such api:
app.get('/api/feedbacks', function(req, res) {
// use mongoose to get all feedbacks in the database
getfeedbacks(res);
});
// create feedback and send back all feedback after creation
app.post('/api/feedbacks', function(req, res) {
// create a feedback, information comes from AJAX request from Angular
FeedBack.create(req.body, function(err, feedback) {
if (err)
res.send(err);
// get and return all the feedbacks after you create another
getfeedbacks(res);
});
});
// delete a feedback
app.delete('/api/feedbacks/:feedback_id', function(req, res) {
FeedBack.remove({
_id : req.params.feedback_id
}, function(err, feedback) {
if (err)
res.send(err);
getfeedbacks(res);
});
});
and such angular service which speaks to node api:
service.factory('FeedBacks', ['$http',function($http) {
return {
create : function(feedBackData) {
return $http.post('/api/feedbacks', feedBackData);
},
get : function() {
return $http.get('/api/feedbacks');
},
delete : function(id) {
return $http.delete('/api/feedbacks/' + id);
}
}
}]);
That way I can post, get and delete data.
My goal is to add also update function.
What I have tried on node:
// update a feedback
app.put('/api/feedbacks/:feedback_id', function(req, res) {
// edit a feedback, information comes from AJAX request from Angular
FeedBack.put(req.body, function(err, feedback) {
if (err)
res.send(err);
// get and return all the feedbacks after you edit one
getfeedbacks(res);
});
});
on Angular service:
update: function(editFeedId, editedFeed){
return $http.put('/api/feedbacks/' + editFeedId, editedFeed);
}
controller looks like:
$scope.editFeed = function(id) {
$scope.editFeedId = id;
$scope.editedFeed = 'replace this txt'
FeedBacks.update($scope.editFeedId, $scope.editedFeed)
// if successful creation, call our get function to get all the new
feedBacks
.success(function(data) {
console.log('updated');
$scope.feedbacks = data;
});
};
I get 500 error as I execute editFeed(). I couldn't figure out to configure that! Where do I do wrong? Any Tips?
Thanks a lot in advance!
I'm assuming you're using Mongo here, in which case your update statement is incorrect.
It should be something like:
app.put('/api/feedbacks/:feedback_id', function(req, res) {
FeedBack.update({_id: req.params.feedback_id}, req.body, function(err, feedback) {
if (err)
res.send(err);
// get and return all the feedbacks after you edit one
getfeedbacks(res);
});
});

Resources