Juan Juan - 4 months ago 37
Node.js Question

How do I return a json surrounded by {} instead of [] on Node.js(express) returning a result of a query using knex and postgresql

if I do a curl request to my node.js(EXPRESS) API curl

http://127.0.0.1:3000/api/events/user/id/1
I get this result:

[{"id":"1","name":"casamiento 1","description":"el casamiento del tio claudio","mode_id":1,"initial_date":"2016-05-28T22:14:57.000Z","end_date":"2016-05-28T22:14:58.000Z","state_id":1,"user_id":"1","location":"0101000020E61000000000000000805BC00000000000003E40"},{"id":"2","name":"casamiento 2","description":"el casamiento del tio claudio 2","mode_id":1,"initial_date":"2016-05-28T22:14:57.000Z","end_date":"2016-05-28T22:14:58.000Z","state_id":1,"user_id":"1","location":"0101000020E61000000000000000405BC00000000000003D40"},{"id":"3","name":"fiesta del sandwich de miga","description":"Nos juntamos a comer sandwiches de miga hasta reventar","mode_id":1,"initial_date":"2016-05-28T22:15:58.000Z","end_date":"2016-05-28T22:15:58.000Z","state_id":1,"user_id":"1","location":"0101000020E610000000000000000000000000000000804840"}]


and I need the output to be surrounded by curly brackets like:

{{"id":"1","name":"casamiento 1","description":"el casamiento del tio claudio","mode_id":1,"initial_date":"2016-05-28T22:14:57.000Z","end_date":"2016-05-28T22:14:58.000Z","state_id":1,"user_id":"1","location":"0101000020E61000000000000000805BC00000000000003E40"},{"id":"2","name":"casamiento 2","description":"el casamiento del tio claudio 2","mode_id":1,"initial_date":"2016-05-28T22:14:57.000Z","end_date":"2016-05-28T22:14:58.000Z","state_id":1,"user_id":"1","location":"0101000020E61000000000000000405BC00000000000003D40"},{"id":"3","name":"fiesta del sandwich de miga","description":"Nos juntamos a comer sandwiches de miga hasta reventar","mode_id":1,"initial_date":"2016-05-28T22:15:58.000Z","end_date":"2016-05-28T22:15:58.000Z","state_id":1,"user_id":"1","location":"0101000020E610000000000000000000000000000000804840"}}


My model "event" file is like this which makes the query to knex and then return the results:

var express = require('express');
var router = express.Router();
var Promise = require("bluebird");
var connectionString = 'postgres://postgres:postgres@localhost:5432/flock';
var knex = require('knex')({
client: 'pg',
connection: connectionString,
searchPath: 'knex,public'
});

//Get all events from a particular user
exports.getUserEvents=function(id_user){



console.log("Retrieving data from id_user: "+id_user);

var promise1 = Promise.try(function () {
return knex('events')
.select('*')
.where('user_id', id_user);
});

var promise2=promise1.then(function (rows) { // this creates a new promise, and the promise created here is what gets returned to the caller
console.log('Returning '+rows.length+' rows from the user with id '+id_user);
return rows;

});

return promise2;
}


and my router file, which calls the model file function getUserEvents, is like this:

var express = require('express');
var router = express.Router();
var Event=require('../models/event');


//get all events from a user

router.get('/user/id/:id_user', function(req, res, next) {

var id_user= req.params.id_user;

var promise = Event.getUserEvents(id_user);

promise.then(function (result) {
console.log('Sending response');
return res.json(result); //<---this line builds the JSON response
});

promise.catch(function (err) {


return res.sendStatus(500);

});

});




module.exports = router


My question is, How do I send the json object list surrounded by {} and not by [] like is returning now?. Thank you very much

EDIT: This solved my problem, the final format is {"rows":{row1},{row2},etc}

exports.getUserEvents=function(id_user){

console.log("Retrieving data from id_user: "+id_user);

var promise1 = Promise.try(function () {
return knex('events')
.select('*')
.where('user_id', id_user);
});

var promise2=promise1.then(function (rows) { // this creates a new promise, and the promise created here is what gets returned to the caller
console.log('Returning '+rows.length+' events from the user with id '+id_user);
**return {rows};**

});

return promise2;


}

Answer

Your api request is returning an array of objects

arrayOfObjects = [
    {objkey: objvalue},
    {objkey: objvalue}
]

You could nest the array in an object like this

newObj = {
    nestedarray: result
}

Or you could return the objects as individual values

newObj = {
    1: result[0],
    2: result[1],
    3: result[2]
}

But all objects need a key value pair.

Note that an Array in Javascript is actually a specialised type of object that still uses property names that happen to be integers, but are optimised to allow specialised methods.

So in your case:

var express = require('express');
var router = express.Router();
var Event=require('../models/event');


//get all events from a user

router.get('/user/id/:id_user', function(req, res, next) {

    var id_user= req.params.id_user;

    var promise = Event.getUserEvents(id_user);

    promise.then(function (result) {
    console.log('Sending response');

    // Option One
    var newObj = {
        nestedarray: result
    }

    // Option Two
    var newObj = {}
    response.forEach(function(elem, index) {
        newObj[index] = elem;
    });

    return res.json(newObj);  //<---this line builds the JSON response
});

   promise.catch(function (err) {

        return res.sendStatus(500); 

   });
});

Note that in both options you do not end up with the format you want simply because it is not possible, but either option gets rid of the array syntax.