Transform answer of REST API - sql

I tried to create a database using sqlite3 and ES6. To receive the data of the database I created REST methods.
When I use GET on the API I receive this answer for example:
{
"user": [
{
value1: tmp,
value2: test,
}
]
}
But I need the answer to be simple JSON, it should be like this
{
"user": {
value1: tmp,
value2: test,
}
}
The code I used for the GET method is:
// GET the user
app.get("/api/userTemplate", (req, res, next) => {
var sql = "select * from user"
var params = []
db.all(sql, params, (err, rows) => {
if (err) {
res.status(400).json({"error":err.message});
return;
}
res.json({
"user":rows
})
});
});
I am aware this will return the full table of users, this is intended.
EDIT: "user":rows[0] works for me, but this returns only one row of the table. Is it possible to modify this in order to return all rows of the table?

Related

Nested data collection via function in mongoose

I don't know if its a dumb way to do this but I have a problem with this get route.
I want to get all the data from mongo in the lower part (find).
In that part I want to sum all data in the database.
for context: I want to display all datasets on the website and all the data as a sum.
Any idea why this isn't working?
router.get('/', function(req, res, next) {
function getSumme(){
stopp.aggregate([
{$group: {
_id: null,
totalLiter: {$sum: "$liter"}
}}
]);
console.log(summe);
};
stopp.find((err, data) => {
if (!err) {
res.render(path + '/index', {
data: data,
test: 123,
stopps: getSumme()
});
} else {
console.log('Failed to retrieve the Course List: ' + err);
}
});
})
Few corrections in your query,
missed async/await method for aggregate query
result the sum by checking turnery operator condition
router.get('/', async function(req, res, next) {
let result = await stopp.aggregate([
{
$group: {
_id: null,
totalLiter: {$sum: "$liter"}
}
}
]);
res.render(path + '/index', {
// data: data,
// test: 123,
stopps: result.length ? result[0].totalLiter : 0
});
})

Why does the 1st middleware of the array needs to call next() but the 2nd does not?

I am new in web development. While following the Node Express Mozilla Tutorial, I came accross this array of controller middlewares that made me confused regarding the use of next().
This array has 3 middlewares:
One for making sure a certain form parameter is in array format
One for doing validation and sintizaiton of the for parameters
One for processing and giving a response to the request
My doubt is: why does the 1st one calls next() but the 2nd does not?
Below the block of code with the array of controller middlewares:
// Handle book create on POST.
exports.book_create_post = [
// Convert the genre to an array.
(req, res, next) => {
if(!(req.body.genre instanceof Array)){
if(typeof req.body.genre ==='undefined')
req.body.genre = [];
else
req.body.genre = new Array(req.body.genre);
}
next();
},
// Validate and sanitise fields.
body('title', 'Title must not be empty.').trim().isLength({ min: 1 }).escape(),
body('author', 'Author must not be empty.').trim().isLength({ min: 1 }).escape(),
body('summary', 'Summary must not be empty.').trim().isLength({ min: 1 }).escape(),
body('isbn', 'ISBN must not be empty').trim().isLength({ min: 1 }).escape(),
body('genre.*').escape(),
// Process request after validation and sanitization.
(req, res, next) => {
// Extract the validation errors from a request.
const errors = validationResult(req);
// Create a Book object with escaped and trimmed data.
var book = new Book(
{ title: req.body.title,
author: req.body.author,
summary: req.body.summary,
isbn: req.body.isbn,
genre: req.body.genre
});
if (!errors.isEmpty()) {
// There are errors. Render form again with sanitized values/error messages.
// Get all authors and genres for form.
async.parallel({
authors: function(callback) {
Author.find(callback);
},
genres: function(callback) {
Genre.find(callback);
},
}, function(err, results) {
if (err) { return next(err); }
// Mark our selected genres as checked.
for (let i = 0; i < results.genres.length; i++) {
if (book.genre.indexOf(results.genres[i]._id) > -1) {
results.genres[i].checked='true';
}
}
res.render('book_form', { title: 'Create Book',authors:results.authors, genres:results.genres, book: book, errors: errors.array() });
});
return;
}
else {
// Data from form is valid. Save book.
book.save(function (err) {
if (err) { return next(err); }
//successful - redirect to new book record.
res.redirect(book.url);
});
}
}
];

Why string is ignored in sql query using express when passing in req.params.id?

I am using express with mysql querying an events database. Everything is working fine but I want to make sure that all undefine routes are properly redirected. I am accessing and displaying the events by their id. I managed to make the redirection when I enter a totally different event id but if I add a random string behind the event id, the query still works - why is that?
So for example:
/32516 -> works as it's a valid id
/32516gjklktj -> still works, why?
/94535 -> doesn't work as it's not a valid id
I am using mysql as the database and the mysql npm package
Events route:
router.get('/:id', (req, res) => {
let eventId = req.params.id
async.parallel({
one: function(callback) {
pool.query(db.EventInfo, [eventId], (err, results) => {
if (err) throw err;
callback(null, results);
});
},
two: function(callback) {
pool.query(db.Bookings, [eventId], (err, results) => {
if (err) throw err;
callback(null, results);
});
}
}, function(err, results) {
if (err) throw err;
if (results.one[0] === undefined) {
res.redirect('/')
} else {
res.render('event', {
event: results.one[0],
bookings: results.two,
});
}});
})
Database query:
let db = {
EventInfo:
`SELECT id, title, date, location FROM events
WHERE eventId=?`,
Bookings:
`SELECT firstName, lastName FROM bookings
WHERE eventId=?`
};
What am I missing? I am still new to coding but learning hard and fast :)

Graphql, node.js and sql,Cannot return null for non-nullable field

I want to return data coming from db to the api. The data is being logged but not showing on the graphql api.
const express = require('express');
const bodyParser = require('body-parser');
const graphqlHttp = require('express-graphql');
const { buildSchema } = require('graphql');
var mysql = require('mysql');
const app = express();
//start mysql connection
var connection = mysql.createConnection({
host : 'localhost', //mysql database host name
user : 'root', //mysql database user name
password : '', //mysql database password
database : 'test' //mysql database name
});
connection.connect(function(err) {
if (err) throw err
})
//end mysql connection
app.use(bodyParser.json());
app.use(
'/graphql',
graphqlHttp({
schema: buildSchema(`
type users {
id: String!
username: String!
password: String!
role: String!
name: String!
photo: String!
}
type RootQuery {
getUsers: [users!]!
}
type RootMutation {
createUsers(name: String): String
}
schema {
query: RootQuery
mutation: RootMutation
}
`),
rootValue: {
getUsers: () => {
connection.query('select * from users', function (error, results, fields) {
if (error) throw error;
console.log(JSON.stringify(results))
return JSON.stringify(results) ;
});
},
createUsers: (args) => {
const eventName = args.name;
return eventName;
}
},
graphiql: true
})
);
app.listen(3000);
RESULT:
query
{
getUsers {
id
}
}
OUTPUT:
{
"errors": [
{
"message": "Cannot return null for non-nullable field RootQuery.getUsers.",
"locations": [
{
"line": 3,
"column": 3
}
],
"path": [
"getUsers"
]
}
],
"data": null
}
This is your resolver:
getUsers: () => {
connection.query('select * from users', function (error, results, fields) {
if (error) throw error;
//users = results;
console.log(JSON.stringify(results));
return JSON.stringify(results) ;
});
},
A GraphQL resolver must return either a value or a Promise that will resolve to a value. However, here, you're not returning either. Keep in mind that callbacks are invoked asynchronously, so returning a value inside a callback does nothing (in most cases).
You really should use something like promise-mysql instead of mysql, but you can still wrap a callback with a Promise and return that Promise. Something like this should work:
getUsers: () => {
// Note, we have to return the Promise here
return new Promise((resolve, reject) => {
connection.query('select * from users', (error, results, fields) => {
if (error) {
reject(error)
} else {
// Don't stringify
resolve(results)
}
})
})
},
getUsers: () => {
/* 👉 return 👈 */ connection.query('select * from users', function (error, results, fields) {
if (error) throw error;
//users = results;
console.log(JSON.stringify(results));
return JSON.stringify(results) ;
});
},
Your getUsers function doesn't return anything. I believe you're missing the return statement I've highlighted in the above comment.
Incidentally, it's best practices in GraphQL to ensure all the root fields (such as getUsers) are nullable, have a read of this article to find out why.
delete (!) from field definition in schema

Express REST API - Delete Method

I am getting stuck on the delete method for my API. My application requires a user to log in and then he can add courses. The courses are stored in a nested array inside the User model. I want the user to be able to cancel (delete) a course from the view and then have the course deleted from the user's profile on the server. I am getting a 404 response event though the variables I am comparing are identical.
This is my ajax call to delete a specific course:
jQuery.ajax({
url: "/test/signups/5387c1a0fb06e48f4658170c",
type: "DELETE",
success: function (data, textStatus, jqXHR) {
console.log("Post resposne:");
console.dir(data);
console.log(textStatus);
console.dir(jqXHR);
}
});
This is my delete method:
app.delete('/test/signups/:id', isLoggedIn, function(req, res) {
User.findOne({'_id': req.user.id }, function(err, user) {
if (err)
return done(err);
if (user) {
var found = false;
var singlesignup = user.signup.filter(function(e){ return e._id == req.params.id })[0]
user.signup.forEach(function (singlesignup, index) {
if (singlesignup._id === req.params.id) {
found = index;
}
});
if(found) {
user.signup.splice(found, 1);
res.json(200, {status: 'deleted'});
} else {
res.json(404, {status: 'invalid survey question deletion'});
}
}
});
});
The _id values in mongodb are not strings, they are instances of the ObjectId class and they don't work correctly with the == or === operators. It's completely a nuisance. But anyway try converting them to strings before comparing: singlesignup._id.toString() === req.params.id. To get it truly correct in the long run, make sure you handle all the cases of null, string or ObjectId. Consider a helper library such as objectid.