Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

I am trying following code at node js using postgres to obtain a list of nested json object like this:

{
    "elements": [
        {
            "name": "element 1",
            "description": "lorem ipsus",
            "docs": [
                {
                    "docs_id": 1053,
                    "docs_file": "../uploads/1461s444---planimetria.pdf",
                    "docs_created_at": "ThuMay14201506: 00: 00GMT+0200(CEST)"
                },
                {
                    "docs_id": 1054,
                    "docs_file": "../uploads/1461s444---VAX-with-highlight.pdf",
                    "docs_created_at": "ThuMay14201506: 00: 00GMT+0200(CEST)"
                },
                {
                    "docs_id": 1055,
                    "docs_file": "../uploads/1461s444---Elaborato-Planimetrico-with-highlight.pdf",
                    "docs_created_at": "ThuMay14201506: 00: 00GMT+0200(CEST)"
                }
            ]
        },
        {
            "name": "element 2",
            "description": "lorem ipsus",
            "docs": [
                {
                    "docs_id": 1056,
                    "docs_file": "../uploads/pianta.pdf",
                    "docs_created_at": "ThuMay17201106: 00: 00GMT+0200(CEST)"
                },
                {
                    "docs_id": 1055,
                    "docs_file": "../uploads/test.pdf",
                    "docs_created_at": "ThuMay16201706: 00: 00GMT+0200(CEST)"
                }
            ]
        }
    ]
}

using this code:

apiRoutes.get('/elements', function(req, res) {

var elements = [];  
knex.select().table('element').where(req.query)
    .then (function(rows){
        for(var i in rows){
            var element =  rows[i];
            knex.select().table('document').where('element_id',rows[i].element_id)
                .then (function(docs){
                    element['docs'] = docs;
                    //console.log (elements);
                    elements.push(element);
                });
        }
        res.json (elements);
    });
});

but the result is an empty array.

I think it's a problem with the asynchronous processing about the queries but I can't solve it.

share|improve this question

1 Answer 1

Your for loop is making a bunch of async calls. You need to return all of them in a promise. Here's an example using bluebird. (I didn't test this yet.)

var Promise = require('bluebird')

knex.select().table('element').where(req.query)
    .then (function(rows){

        var promises = rows.map(function(element){
            return knex.select().table('document').where('element_id',element.element_id)
                .then(function(docs){
                    element['docs'] = docs

                    return element;
                });
        })

       return Promise.all(promises)     
    }).then(function(elements){     
        res.json (elements);
    })
});

However, I think issuing the second query is an n+1. Knex supports a left outer join. You should use that.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.