hapijs getting form data - database

I am trying to get the data from my form into my hapijs server. I don't seem to be managing. When I submit the form, the data is passed as undefined which trigers an error on the server. From what I understand hapi parses the data automatically.
Could someone please help me understand what I am doing wrong? Why am I getting undefined?
The function that handles the form data is sendworkout.
These are my routes:
var path = require('path');
var _ = require('underscore');
var couchbase = require('couchbase');
//Connect to database.
var db = db || new couchbase.Connection({host: 'localhost:8091', bucket: 'default'}, function(err) {
if (err) {
console.log('Connection Error', err);
} else {
console.log('Connected!');
}
});
console.log(db);
//We have a pending connection to the test database running on localhost.
//We now need to get notified if we connect successfully or if a connection error occurs
var landingPage = {
handler: function(req, reply) {
reply.file('index.html');
}
};
var getWorkouts = {
handler: function (req, reply) {
// set options for databse query
var q ={
descending: true,
stale: false
};
// show multiple exercises - db.view(designDocument, viewName, options)
db.view('workout', 'exercise', q).query(function(err, values){
// use pluck method from underscore to retrieve data
var keys = _.pluck(values, 'id');
console.log("Keys: " + keys);
//fetch multiple documents based on the 'keys' object
db.getMulti(keys, null, function(err, results){
console.log('Results: ' + results);
var workouts = [];
for (var prop in results) {
workouts.push(results[prop].value);
}
reply(workouts);
});
});
}
};
var getMusclegroup = {
handler: function (req, reply) {
var q = {
descending: true,
stale: false
};
db.view('workout', 'exercise', q).query(function(err, values){
var keys = _.pluck(values, 'id');
db.getMulti(keys, null, function(err, results){
var muscleGroups = [];
for (var prop in results) {
console.log(typeof results);
console.log(results[prop].value.workout);
muscleGroups.push(results[prop].value.workout);
}
reply(muscleGroups[0]);
});
});
}
};
var sendWorkout = {
handler: function(req, reply){
var d = new Date();
var cd = d.getDate() + "-" + (d.getMonth()+1) + "-" + d.getFullYear();
console.log(req.method); // getting a post method - OK
console.log(req.body); // returns undefined
// defines unique key for data
var key = cd;
console.log(key);
// adds payload to database
db.add(key, req.body, function(error, results){
if (error) {
console.log("Coushbase error: " + error);
reply(error + "\n");
}
console.log(results);
reply(req.body);
});
}
};
var workoutNew = {
handler: function (req, reply) {
reply.file("static/html/workoutForm.html");
},
};
module.exports = [
{method: 'GET', path: '/static/{param*}', config: { handler: { directory: { path: 'static'}}}},
{method: 'GET', path: '/', config: landingPage},
{method: 'GET', path: '/workouts', config: getWorkouts},
{method: 'GET', path: '/workouts/musclegroup', config: getMusclegroup},
{method: 'GET', path: '/newworkout', config: workoutNew},
{method: 'POST', path:'/newworkout/workout', config: sendWorkout}
];
This is my server module:
var Hapi = require('hapi');
var path = require('path');
var Joi = require('joi');
var rs = require('./lib/modules/routes.js');
var config= { };
var server = Hapi.createServer(process.env.PORT || 8080, config);
server.route(rs);
server.start(function(){
console.log("Server started: " + server.info.uri);
});
module.exports = server;
This is my html form:
<div id="forms">
<form id="workout-form" name="workout-form" action="newworkout/workout" method="POST">
<div class="workouts">
<label for="exercise" class="labels">Exercise</label><input type="text" name="exercise" id="exercise" placeholder="Which exercise?" autofocus />
<label for="musclegroup" class="labels">Muscle-Group</label><input type="text" name="musclegroup" id="musclegroup" placeholder="Which muscle-group?" />
<div class="sets">
<label for="reps" class="labels">Reps</label><input type="text" name="reps" id="reps" class="reps-column" placeholder="How many reps?" />
<label for="kilos" class="labels">Kg's</label><input type="text" name="kilos" id="kilos" class="kilos-column" placeholder="How much Kg?" />
</div>
<hr>
</div>
<button id="add-set"class="add-buttons" type="button"><i class="fa fa-plus-circle fa-2x"></i></button>
<button id="add-exercise" class="add-buttons" type="button"><i class="fa fa-arrow-circle-down fa-2x"></i></button>
<button id="submit-workout" type="submit" name="submitbutton"><strong>Save Workout</strong></button>
</form>
</div>

Just replace req.body with req.payload:
var path = require('path');
var _ = require('underscore');
var couchbase = require('couchbase');
//Connect to database.
var db = db || new couchbase.Connection({host: 'localhost:8091', bucket: 'default'}, function(err) {
if (err) {
console.log('Connection Error', err);
} else {
console.log('Connected!');
}
});
console.log(db);
//We have a pending connection to the test database running on localhost.
//We now need to get notified if we connect successfully or if a connection error occurs
var landingPage = {
handler: function(req, reply) {
reply.file('index.html');
}
};
var getWorkouts = {
handler: function (req, reply) {
// set options for databse query
var q ={
descending: true,
stale: false
};
// show multiple exercises - db.view(designDocument, viewName, options)
db.view('workout', 'exercise', q).query(function(err, values){
// use pluck method from underscore to retrieve data
var keys = _.pluck(values, 'id');
console.log("Keys: " + keys);
//fetch multiple documents based on the 'keys' object
db.getMulti(keys, null, function(err, results){
console.log('Results: ' + results);
var workouts = [];
for (var prop in results) {
workouts.push(results[prop].value);
}
reply(workouts);
});
});
}
};
var getMusclegroup = {
handler: function (req, reply) {
var q = {
descending: true,
stale: false
};
db.view('workout', 'exercise', q).query(function(err, values){
var keys = _.pluck(values, 'id');
db.getMulti(keys, null, function(err, results){
var muscleGroups = [];
for (var prop in results) {
console.log(typeof results);
console.log(results[prop].value.workout);
muscleGroups.push(results[prop].value.workout);
}
reply(muscleGroups[0]);
});
});
}
};
var sendWorkout = {
handler: function(req, reply){
var d = new Date();
var cd = d.getDate() + "-" + (d.getMonth()+1) + "-" + d.getFullYear();
console.log(req.method); // getting a post method - OK
console.log(req.payload);
// defines unique key for data
var key = cd;
console.log(key);
// adds payload to database
db.add(key, req.payload, function(error, results){
if (error) {
console.log("Coushbase error: " + error);
reply(error + "\n");
}
console.log(results);
reply(req.payload);
});
}
};
var workoutNew = {
handler: function (req, reply) {
reply.file("static/html/workoutForm.html");
},
};
module.exports = [
{method: 'GET', path: '/static/{param*}', config: { handler: { directory: { path: 'static'}}}},
{method: 'GET', path: '/', config: landingPage},
{method: 'GET', path: '/workouts', config: getWorkouts},
{method: 'GET', path: '/workouts/musclegroup', config: getMusclegroup},
{method: 'GET', path: '/newworkout', config: workoutNew},
{method: 'POST', path:'/newworkout/workout', config: sendWorkout}
];

Related

How to query mongodb on a specific field

I have a collection of objects with the following schema :
var Meetup = new Schema({
name: String,
text:String,
});
I would like to get all of the meetups whom name contain a string.
Here is my api :
module.exports.list = function (req, res) {
Meetup.find({}, function (err, results) {
res.json(results);
});
}
and in my angular controller i have :
var Meetup = $resource('/api/meetups');
$scope.meetups = []
Meetup.query(function (results) {
$scope.meetups = results;
});
can anyone help
Query on specific field
ModelName.find({fieldName: value}, function (err, results) {
//...
});
so for your case query will be like:
exports.list = function (req, res) {
Meetup.find({name: req.query.name}, function (err, results) {
res.json(results);
});
};
and angular controller like
var Meetup = $resource('/api/meetups', {}, {
query: {method: 'get', isArray: true}
});
$scope.meetups = []
Meetup.query({name: 'yourName'}).$promise.then(function(results) {
// console.log(results);
$scope.meetups = results;
}, function(error) {
// console.log(error);
$scope.meetups = [];
});

unable to store base 64 image in mongodb

I have a requirement to store base 64 image data captured using webcam js in mongodb
I tried to store the image data in mongodb but unable to do so
Server
schema:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ProfilesSchema = new Schema({
name: String,
otherFiles: [Object]
});
module.exports = mongoose.model('Profiles', ProfilesSchema);
express js :
exports.otherFiles = function(req, res) {
console.log("b4" + req.body.key.imgDataField);
var base64Image = new Buffer(req.body.key.imgDataField, 'binary').toString('base64');
req.body.key.imgDataField = base64Image;
console.log("after" + req.body.key.imgDataField);
Profiles.update({
"_id": req.params.id
}, {
$push: {
"otherFiles": {
imgDataField: req.body.key.imgDataField
}
}
}, function(error, profiles) {
if (error) {
}
return res.status(200).json(fnStruncturedData(profiles));
});
};
Client
controller:
$scope.take_snapshot = function() {
debugger;
Webcam.snap(function(data_uri) {
$scope.data = data_uri;
$scope.oData = {};
$scope.oData.imgDataField = data_uri;
getCandidateInterviewListService.fnSavefiles(localStorage.getItem('candidateID'), $scope.oData).then(function(response) {});
document.getElementById('my_result').innerHTML = '<img src="' + data_uri + '"/>';
//console.log($scope.data);
});
$scope.set = true;
}
service:
this.fnSavefiles = function(id, sData) {
debugger;
return ajaxServiceManager.fnQuery({
sUrl: 'http://192.168.208.31:4000/onboardvue/profiles/otherFiles/' + id,
sMethod: "PUT",
oData: {
key: sData
}
});
};
Please help me with this
I am using mongodb ,express js
I store a base 64 image like this:
MyController.js
exports.addBook = function (req, res) {
'use strict';
var book = new Book({
title : req.body.title,
author : req.body.author,
category : req.body.category,
synopsis : req.body.synopsis,
units : req.body.units,
avatar: {
data : base64Image('your path' + req.body.avatar + '.jpg'),
contentType: 'image/png'
}
});
function base64Image(src) {
return fs.readFileSync(src).toString("base64");
}
book.save(function (err, books) {
if (err) {
return res.status(500).send(err.message);
}
res.status(200).jsonp(books);
});
};
Hope it helps you

Angular resolve promise and update existing scope

I am trying to understand Angular's promises and scopes. Actually I implemented the directive bellow. The thing that I want to do is to receive images from server and store locally in order to cache them for next times. Also I want to show a spinner before the load of image is completed and show it after the completion.
How can update variable newUrl into directive when completed all of these promises?
Do you have any idea?
My HTML code is:
<div style="text-align: center;"
cache-src
url="https://upload.wikimedia.org/wikipedia/commons/c/c0/Aix_galericulata_(Male),_Richmond_Park,_UK_-_May_2013.jpg">
</div>
My directive is:
.directive('cacheSrc', [function () {
return {
restrict: 'A',
scope: {
url: '#'
},
controller: 'cacheSrcCtrl',
template: '<img width="100%" ng-if="newUrl!=null" src="{{newUrl}}"><ion-spinner ng-if="newUrl==null" icon="spiral"></ion-spinner>',
};
}])
And the controller of directive has the function bellow:
document.addEventListener('deviceready', function () {
$scope.updateUrl = function (newUrl) {
$scope.newUrl = newUrl;
};
var tmp = $scope.url;
$cordovaSQLite.execute(db, 'SELECT * FROM images where url = (?)', [tmp])
.then(function (result) {
if (result.rows.length > 0) {
$scope.exists = true;
for (var i = 0; i < res.rows.length; i++) {
var image = {
id: res.rows.item(i).id,
url: res.rows.item(i).url,
uri: res.rows.item(i).uri
};
$scope.updateUrl(image.uri);
}
} else {
$scope.exists = false;
var fileTransfer = new FileTransfer();
var uri = encodeURI(tmp);
var uriSave = '';
var fileURL = cordova.file.dataDirectory + uri;//'kaloudiaImages';// + getUUID();// + "DCIM/myFile";
fileTransfer.download(
uri, fileURL, function (entry) {
uriSave = entry.toURL();
KaloudiaDB.add(tmp, fileURL);
$scope.newUrl = fileURL;
$scope.updateUrl(fileURL);
},
function (error) {
console.log("download error code" + error.code);
},
false, {
headers: {
// "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
).then(function (data) {
$scope.newUrl = fileURL;
});
}
}, function (error) {
$scope.statusMessage = "Error on saving: " + error.message;
})
.then(function (data) {
$scope.$apply(function () {
$scope.newUrl = fileURL;
});
});
});

angular.js - TypeError: Cannot read property 'then' of undefined

I'm trying to insert a details page of each of my captures using my service.
Though when I try loading the page with an id in my service (example: /capture/5740c1eae324ae1f19b7fc30) I get undefined, using this code:
app.factory('captureApi', ['$http', function($http){
var urlBase = 'URL';
// ==> Gives back an array as such:
//[
//{
// "_id": "5740c1e3e324ae1f19b7fc2f",
// "created_at": "2016-05-21T20:15:38.554Z",
// "userId": "118000609287736585411",
// "place": "place",
// "birdname": "birdname",
// "__v": 0
//},
//{
// "_id": "5740c1eae324ae1f19b7fc30",
// "created_at": "2016-05-21T20:15:38.554Z",
// "userId": "118000609287736585411",
// "place": "place",
// "birdname": "birdname",
// "__v": 0
//},
//{
// ...
//}
//]
return {
getAllCaptures : function () {
return $http.get(urlBase);
},
insertCapture : function(data) {
return $http.post(urlBase, data);
},
findCapture : function(id) {
//both give undefined
console.log(_.find(urlBase, function(capture){return capture._id == id}));
console.log(_.find(urlBase, function(capture){return capture.id == id}));
return _.find(urlBase, function(capture){return capture.id == id});
}
}
}]);
On the server side I am using mongoose/mongodb:
-route:
var Capture = require('../models/capture');
module.exports = function(router) {
router.post('/captures', function(req, res){
var capture = new Capture();
capture.birdname = req.body.birdname;
capture.place = req.body.place;
capture.userId = req.body.userId;
capture.author = req.body.author;
capture.picture = req.body.picture;
capture.created_at = new Date();
capture.save(function(err, data){
if(err)
throw err;
console.log(req.body);
res.json(data);
});
});
router.get('/captures', function(req, res){
Capture.find({}, function(err, data){
res.json(data);
});
});
router.delete('/captures', function(req, res){
Capture.remove({}, function(err){
res.json({result: err ? 'error' : 'ok'});
});
});
router.get('/captures/:id', function(req, res){
Capture.findOne({_id: req.params.id}, function(err, data){
res.json(data);
});
});
router.delete('/captures/:id', function(req, res){
Capture.remove({_id: req.params.id}, function(err){
res.json({result: err ? 'error' : 'ok'});
});
});
// router.post('/captures/:id', function(req, res){
// Capture.findOne({_id: req.params.id}, function(err, data){
// var capture = data;
// capture.birdname = req.body.birdname;
// capture.place.city = req.body.place.city;
// capture.place.country = req.body.place.country;
// capture.save(function(err, data){
// if(err)
// throw err;
// res.json(data);
// });
// })
// })
}
-model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var captureSchema = mongoose.Schema({
birdname: {type: String, required: true},
place: {type: String, required: true},
userId: {type: String, required: true},
author: {type: String, required: true},
picture: Schema.Types.Mixed,
created_at: Date
});
module.exports = mongoose.model('Capture', captureSchema)
Here is my server.js (extra info):
// Init Express Web Framework
var express = require('express');
var app = express();
var path = require('path');
// Set view engine to EJS & set views directory
app.set('view engine', 'ejs');
app.set('views', path.resolve(__dirname, 'client', 'views'));
app.use(express.static(path.resolve(__dirname, 'client')));
// Database Connection
var mongoose = require('mongoose');
var configDB = require('./server/config/database.js');
mongoose.connect(configDB.url);
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.text());
app.use(bodyParser.json({ type: 'application/json'}));
// Main route
app.get('/', function(req, res){
res.render('index.ejs');
});
// // catch 404 and forwarding to error handler
// app.use(function(req, res, next) {
// var err = new Error('Not Found');
// err.status = 404;
// next(err);
// });
// API
var api = express.Router();
require('./server/routes/capture')(api);
app.use('/api', api);
// Set routes to other pages
app.get('/*', function(req, res){
res.render('index.ejs');
});
// Port Settings
app.listen(process.env.PORT || 3000, process.env.IP);
console.log('Listening on port ' + process.env.PORT);
On the client side I have the following the trigger the page:
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/home.html',
controller: 'homeCtrl',
data: {
requiresLogin: false
},
resolve: {
$title: function() { return 'Home'; }
}
})
.state('dash', {
url: '/dashboard',
templateUrl: 'partials/dashboard.html',
controller: 'dashCtrl',
data: {
requiresLogin: true
},
resolve: {
$title: function() { return 'Dashboard'; }
}
})
.state('capture', {
url: '/capture',
templateUrl: 'partials/capture.html',
controller: 'captureCtrl',
data: {
requiresLogin: true
},
resolve: {
$title: function() { return 'Capture'; }
}
})
.state('viewCapture', {
url: '/capture/:id',
templateUrl: 'partials/viewCapture.html',
controller: 'viewCaptureCtrl',
data: {
requiresLogin: true
},
resolve: {
$title: function() { return 'Capture Detail'; }
}
})
viewCaptureCtrl.js:
app.controller('viewCaptureCtrl', ['$scope', 'captureApi', '$stateParams', '$http', function($scope, captureApi, $stateParams, $http) {
var id = $stateParams.id;
$scope.viewCapture = function() {
captureApi.findCapture(id)
.then(function(data) {
$scope.capture = data;
});
};
$scope.viewCapture();
}]);
Anyone have an idea why my find function is giving an undefined?
Help is much appreciated! Thanks
You'll need to reference underscoreJS and inject it into your service. Document: http://app-genesis.com/underscorejswithangularjs/
var app = angular.module("app", []);
app.factory('_', function() { return window._; });
//inject into capture api factory
app.factory('captureApi', ['$http', '_', function($http, _){
//do stuff with _
}]);
Edit: But I'm not familiar with _.find(); if it returns a promise or not. If not, you'll need to make use of $q to create a promise and return it in order to use then().
//inject into capture api factory
app.factory('captureApi', ['$http', '_', '$q',
function($http, _, $q) {
return {
findCapture: function(id) {
var deferred = $q.defer();
try {
var results = _.find(); //do stuff with _
deferred.resolve(results);
} catch (err) {
deferred.reject(err);
}
//you need to return a promise in order to use then()
return deferred.promise;
}
}
}
]);

angular, node + Service that returns SQL Data as json

Total newbee here. Given this service.js how can I go about returning terms data from sql server
app.service('termsService', function () {
this.getTerms = function () {
return terms
};
var terms = [
{
termid: 11, term: 'Shanika', termDefinition: 'Passmore'
}
];
});
The code below works well on its own so I want to return terms data in the service call above
var sql = require('msnodesql')
, nconf = require('nconf')
,express = require('express');
nconf.env()
.file({ file: 'config.json' });
var connectionString = nconf.get("SQL_CONN");
var app = express();
app.configure(function () {
app.use(express.bodyParser());
});
app.get("/", function(req, res) {
sql.open(connectionString, function(err, conn) {
if(err) {
}
else {
conn.queryRaw("SELECT TOP 10 termid, term, termDefinition FROM Terms", function(err, results) {
if(err) {
}
else {
res.json(results);
}
});
}
});
});
app.listen(3000);
A code for your angular service :
function Service($http) {
var Service = {};
Service.getCriteria = function (criteria,callback) {
$http({
url: "YOUR URL",
params: criteria,
method: "GET",
isArray: true
}).success(callback)
}
return Service;
}
Be aware of that is an async call, so use promises, callback or sync methods.

Resources