'Can not read property' length 'of undefined' nodeJS

0

I have this query

getAnalysisDetailed: function (req, res, next) {

var config = require('.././database/config');

sql.connect(config).then(function() {
    var articulos = null;
    var request = new sql.Request();
    request.query("SELECT TOP 10  SI_Id_Inventario, SI_Articulo, SI_UM, SI_Ubicacion FROM SI_Inventario_Teorico_QAD").then(function(err, rows, recordset) {
        articulos = rows || [];
        console.log('Recordset: ' + recordset);
        console.log('Affected: ' + request.rowsAffected);
    }).catch(function(err) {
        console.log('Request error: ' + err);
    });
}).catch(function(err) {
    if (err) {
        console.log('SQL Connection Error: ' + err);
    }

});
sql.close();
// send records as a response 
res.render('menu/analisisDetallado', { ListArticulos: articulos });

}

and I need to add what it brings to a table

  div(class="container aDetallado")
    div(class="row center span10")
      table(id="test-table" class="table table-striped table-hover table-condensed")
        thead
          tr
            th='ID'
            th='Articulo'
            th='Um'
            th='#Ubic'        
          tbody
            each Articulos in ListArticulos
              tr
                td= Articulos.SI_Id_Inventario
                td= Articulos.SI_Articulo
                td= Articulos.SI_UM
                td= Articulos.SI_Ubicacion

and I get the following error

  

TypeError: D: \ Physical Inventory Project   Soc \ InventoryF \ views \ menu \ detailed analysis.jade: 59       57 | th = 'Ubic'
      58 | tbody

     
    

59 | each Articles in ListArticles         60 | tr         61 | td = Articles.SI_Id_Inventario         62 | td = Articles.SI_Articulo

  
     

Can not read property 'length' of undefined

    
asked by Eduard 22.06.2017 в 15:26
source

3 answers

1

res.render is being called before the promise of sql.connect is resolved and also the variable articulos is not declared in the same scope as the call to res.render .

Remember that all code within the .then callback is asynchronous.

The proposed solution is to move the lines:

sql.close();
res.render('menu/analisisDetallado', { ListArticulos: articulos });

within the call to .then of request.query

{
    getAnalisisDetallado: function(req, res, next) {

        var config = require('.././database/config');

        sql.connect(config)
            .then(function () {
                var articulos = null;
                var request = new sql.Request();
                request.query("SELECT TOP 10  SI_Id_Inventario, SI_Articulo, SI_UM, SI_Ubicacion FROM SI_Inventario_Teorico_QAD")
                    .then(function (result) {
                        articulos = result.recordset || [];
                        console.log('Recordset: ' + result.recordset);
                        console.log('Affected: ' + request.rowsAffected);
                        sql.close();
                        res.render('menu/analisisDetallado', { ListArticulos: articulos });
                    })
                    .catch(function(err) {
                        console.log('Request error: ' + err);
                    });
            })
            .catch(function (err) {
                if (err) {
                    console.log('SQL Connection Error: ' + err);
                }
            });
    }
}
    
answered by 22.06.2017 / 17:02
source
1

I think the problem is here:

// quito el request.query porque el formato queda poco legible
.then(function(err, rows, recordset) {
                if (err) console.log(err)
                articulos = rows;
                ....

The problem is that, if you fail the promise that you're calling, anyway you call

res.render('menu/analisisDetallado', { ListArticulos: articulos });

You have to find a way to guarantee (in case you have to always call it) that articles have an array.

 articulos = rows || [];

The above code should work for you. If rows comes undefined or null then you assign an empty array.

EDITED

The error with Promise comes up because you do not handle the failed results. I give you an example

var articulo = []
then(function () {
     console.log("Aqui fue bien");
     articulo = rows
}).catch(function () {
     console.log("Aqui fue mal");
});

res.render('menu/analisisDetallado', { ListArticulos: articulos });
    
answered by 22.06.2017 в 15:42
0

According to the mssql library, in its 4.x version you can use asynchronous functions, for this you need or higher:

getAnalysisDetailed (data)

const sql = require('mssql');
const config = require('../../database/config');

const getAnalisisDetallado = async function () {
  try {
    await sql.connect();
    const request = new sql.Request();
    const articulos = request.query'SELECT TOP 10  SI_Id_Inventario, SI_Articulo, SI_UM, SI_Ubicacion FROM SI_Inventario_Teorico_QAD';
    return articulos;
  } catch(e) {
    throw new Error(e.message);
  }
}

getAnalysisDetailed (handler)

getAnalasisDetallado = (req, res) => {
  getAnalisisDetallado()
    .then(articulos => {
      res.render('menu/analisisDetallado', { ListaArticulos: articulos });
    })
    .catch(err => {
      res.render('menu/analisisDetallado', { ListaArticulos: [], error: err });
    });
}

In the 3.x version, you can use any old version ( 4.x +), since there is no support for asynchronous functions:

const getAnalisisDetallado = async function () {
  return (
    sql
      .connect()
      .then((resolve, reject) => {
        const request = new sql.Request();
        request
          .query('SELECT TOP 10  SI_Id_Inventario, SI_Articulo, SI_UM, SI_Ubicacion FROM SI_Inventario_Teorico_QAD')
          .then((err, rows, recorset) => {
            if (err) { reject(err.message); }
            resolve(rows);
          });
      })
  );
}
    
answered by 22.06.2017 в 16:55