1

I have an application in NodeJs with Express, where I get two values:

One is an INTEGER type from Google BigQuery. The other is an int autoincrement length 11 id from MySql via Sequelize.

They are equal values, but when I compare the two I got false:

laboratorios.some(laboratorio => {
    console.log(venda.fornecedor, typeof venda.fornecedor)
    console.log(laboratorio.laboratorio_id, typeof laboratorio.laboratorio_id)
    console.log(laboratorio.labotatorio_id == venda.fornecedor)
    if (laboratorio.labotatorio_id == venda.fornecedor){
        lab = laboratorio.lab_razao_social
        return true;
    }
    return false;
});

Returns on console:

2128 number
2128 number
false

As you can see, they are both "number" of value 2128, I compare them with ==, and still get false. I tried comparing them with === just in case, but also returned false.

Here is how I retrieve the bigquery value:

let query = `SELECT itens.laboratorio_id AS fornecedor,
            ...
            from produtos,
            UNNEST(itens) AS itens
            WHERE ...`;
const options = {
    query: query + ` GROUP BY itens.laboratorio_id;`,
    params: params
};
var [vendas] = await bigqueryClient.query(options).catch(err => {
    ...
});

Here is how I retrieve the Sequelize value:

query = `SELECT laboratorio_id, lab_razao_social FROM laboratorio
            WHERE laboratorio_id IN (:fornecedores)`;
params.fornecedores = fornecedores;

var laboratorios = await sequelize.query(query, {
    type: QueryTypes.SELECT,
    replacements: params
}).catch(err => {
    ...
});

I managed to solve the problem casting both values to int using parseInt:

laboratorios.some(laboratorio => {
    const test1 = parseInt(venda.fornecedor)
    const test2 = parseInt(laboratorio.laboratorio_id)
    console.log(test1, typeof test1)
    console.log(test2, typeof test2)
    console.log(test1 == test2)
    if (test1 == test2){
        lab = laboratorio.lab_razao_social
        return true;
    }
    return false;
});

But still, why they were returning false in first place?

It makes no sense, since js would accept string == int and float == int if the values were the same. They are both integers, so there's no decimal cases, and if it was the case, console.log would shows decimal cases if there was any.

Edit:

The entire function for reference, the above code was just the parts I thought were relevant, but maybe there's something else:

async function graficoVenda(data, session, agrupamento){
    if('dataInicio' in data) {
        dataInicio = data.dataInicio;
        dataFim = data.dataFim;
    } else {
        dataInicio = moment().startOf('month').format('YYYY-MM-DD');
        dataFim = moment().endOf('month').format('YYYY-MM-DD');
    }

    params = {dataInicio: dataInicio, dataFim: dataFim};

    if (agrupamento == 'categoria') {
        let query = `SELECT COALESCE(NULLIF(itens.produto_tipo,''), 'SEM CATEGORIA') AS categoria,
                    SUM(itens.valor_total) AS total,
                    SUM(itens.quantidade) AS qtd,
                        ARRAY(SELECT AS STRUCT ROUND(SUM(itens.valor_total), 2) AS total_devolucao,
                        SUM(itens.quantidade) AS qtd_und_devolucao,
                        COALESCE(NULLIF(itens.produto_tipo,''), 'SEM CATEGORIA') AS categoria
                        from ${table},
                        UNNEST(itens) AS itens
                        WHERE rn = 1
                        AND data >= @dataInicio AND data <= @dataFim AND itens.situacao = 'DEVOLUCAO'
                        GROUP BY itens.produto_tipo ORDER BY total_devolucao DESC) AS devolucao
                    from ${table},
                    UNNEST(itens) AS itens
                    WHERE rn = 1
                    AND pedido.data >= @dataInicio
                    AND pedido.data <= @dataFim
                    AND pedido.situacao = 'CONFIRMADO'
                    AND itens.situacao = 'CONFIRMADO'`;
        [query,params] = FiltroEmpresa.filtroPedido(session, query, params);
        query += ` GROUP BY itens.produto_tipo ORDER BY total DESC`;
        const options = {
            query: query + `;`,
            params: params,
        };
        var [vendas] = await bigqueryClient.query(options).catch(err => {
            messages = err.errors.map(error => { return error.message; });
            throw new Error("Ocorreu um erro de banco de dados: "+messages.join(". ")+".");
        });
        const { devolucao } = vendas[0];
        var categoriaDevolucao = devolucao.map(venda => venda.categoria);
        var categorias = [];

        vendas.forEach(function(venda, index){
            let total, qtd;
            if(categoriaDevolucao.includes(venda.categoria)){
                total = Math.round((venda.total - devolucao[categoriaDevolucao.indexOf(venda.categoria)]['total_devolucao']) * 100) / 100
                qtd = venda.qtd - devolucao[categoriaDevolucao.indexOf(venda.categoria)]['qtd_und_devolucao']
                retorno = {nome: venda.categoria, total: total, qtd: qtd}
            } else{
                retorno = {nome: venda.categoria, total: Math.round(venda.total * 100) / 100, qtd: venda.qtd}
            }
            categorias[index] = retorno;
        });
        return categorias;
    } else if (agrupamento == 'fornecedor'){
        let query = `SELECT itens.laboratorio_id AS fornecedor,
                    SUM(itens.valor_total) AS total,
                    SUM(itens.quantidade) AS qtd,
                        ARRAY(SELECT AS STRUCT ROUND(SUM(itens.valor_total), 2) AS total_devolucao,
                        SUM(itens.quantidade) AS qtd_und_devolucao,
                        itens.laboratorio_id AS fornecedor
                        from ${table},
                        UNNEST(itens) AS itens
                        WHERE rn = 1
                        AND data >= @dataInicio AND data <= @dataFim AND itens.situacao = 'DEVOLUCAO'
                        GROUP BY itens.laboratorio_id ORDER BY total_devolucao DESC) AS devolucao
                    from ${table},
                    UNNEST(itens) AS itens
                    WHERE rn = 1
                    AND pedido.data >= @dataInicio
                    AND pedido.data <= @dataFim
                    AND pedido.situacao = 'CONFIRMADO'
                    AND itens.situacao = 'CONFIRMADO'`;
        [query,params] = FiltroEmpresa.filtroPedido(session, query, params);
        const options = {
            query: query + ` GROUP BY itens.laboratorio_id ORDER BY total DESC;`,
            params: params,
        };
        var [vendas] = await bigqueryClient.query(options).catch(err => {
            messages = err.errors.map(error => { return error.message; });
            throw new Error("Ocorreu um erro de banco de dados: "+messages.join(". ")+".");
        });

        if (vendas){
            var fornecedores = [];
            vendas.forEach(function(venda){
                fornecedores.push(venda.fornecedor)
            });
    
            query = `SELECT laboratorio_id, lab_razao_social FROM laboratorio
                        WHERE laboratorio_id IN (:fornecedores)`;
            params.fornecedores = fornecedores;
    
            var laboratorios = await sequelize.query(query, {
                type: QueryTypes.SELECT,
                replacements: params
            }).catch(err => {
                throw new Error("Ocorreu um erro de banco de dados: "+err.original.sqlMessage);
            });
    
            forn = [];
            const { devolucao } = vendas[0]
            var fornecedorDevolucao = devolucao.map(venda => venda.fornecedor);
            vendas.forEach(function(venda, index){
                let total, qtd;
                if(fornecedorDevolucao.includes(venda.fornecedor)){
                    total = Math.round((venda.total - devolucao[fornecedorDevolucao.indexOf(venda.fornecedor)]['total_devolucao']) * 100) / 100
                    qtd = venda.qtd - devolucao[fornecedorDevolucao.indexOf(venda.fornecedor)]['qtd_und_devolucao']
                    retorno = {total: total, qtd: qtd}
                } else{
                    retorno = {total: Math.round(venda.total * 100) / 100, qtd: venda.qtd}
                }
                let lab = "";
                laboratorios.some(laboratorio => {
                    const aux1 = parseInt(venda.fornecedor)
                    const aux2 = parseInt(laboratorio.laboratorio_id)
                    if (aux1 == aux2){
                        lab = laboratorio.lab_razao_social
                        return true;
                    }
                    return false;
                });
                retorno['nome'] = lab
                forn[index] = retorno;
            });
            return forn;
        }
        return [];
    }
    return false;
}
Leno Oliveira
  • 105
  • 1
  • 12
  • 2
    Going from `==` to `===` can never make a false comparison turn true. Only the other way around. – Barmar Jan 13 '21 at 22:26
  • @jfriend00 The `if` statement seems irrelevant. The fact that it logs `false` when the values are the same is the problem all by itself. – Barmar Jan 13 '21 at 22:40
  • @Barmar - Yep, didn't notice that third log statement. I was looking for something going on here that is confusing what we're seeing because those three log statements don't seem feasible. So somewhere someone is being confused about what they think is actually happening. Do you know of any way that those three log statements could all be output in the same iteration of the loop on the same variables and not end up inside the `if` statement? I don't. So, that's probably not what is happening. Something else is confusing the output. – jfriend00 Jan 13 '21 at 22:45
  • A simple step through this loop in the debugger would probably show you what is happening. – jfriend00 Jan 13 '21 at 22:49
  • Is there more to this `.some()` loop than you actually posted? Are you 200% sure that the results you show `2128 number 2128 number false` come from the same iteration through the loop? – jfriend00 Jan 13 '21 at 22:50
  • This is the entire loop, there is nothing else, I just cut the logs of all other iterations that didn't matter, they show a bunch of different numbers with false bellow. About the `===`, I tried both comparisons just to be sure because js is crazy – Leno Oliveira Jan 14 '21 at 07:46
  • I'll preface by saying I don't know Node/Javascript, but BQ integer is a 64-bit type `INT64` while MySQL integer type is a 32-bit type `INT`. Would it help to `cast()` your MySQL `INT` as a `BIGINT` (64 bits)? Not sure if this matters once the data is returned to your environment. – rtenha Jan 14 '21 at 18:28
  • rtenha javascript doesn't even have a "big int" type, all ints are 32 bits. https://stackoverflow.com/questions/9643626/does-javascript-support-64-bit-integers – Leno Oliveira Jan 15 '21 at 08:43

0 Answers0