Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Ligação do objeto app (custom-express.js) com o módulo rotas.js através do código rotas(app)

Olá pessoal!

Seguem códigos para posterior explicação da dúvida:

// arquivo rotas.js
module.exports = (app) => {

    app.get('/', function(req, resp) {
        resp.send(
            `
                <html>
                    <head>
                        <meta charset="utf-8">
                    </head>
                    <body>
                        <h1> Casa do Código </h1>
                    </body> 
                </html>
            `
        );
    });

    app.get('/livros', function(req, resp) {
        resp.send(
            `
                <html>
                    <head>
                        <meta charset="utf-8">
                    </head>
                    <body>
                        <h1> Listagem de livros </h1>
                    </body> 
                </html>
            `
        );
    });

}
// parte do código do arquivo custom-express.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const methodOverride = require('method-override');

app.use('/estatico', express.static('src/app/public'));

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(methodOverride(function (req, res) {
    if (req.body && typeof req.body === 'object' && '_method' in req.body) {
      // look in urlencoded POST bodies and delete it
      var method = req.body._method;
      delete req.body._method;
      return method;
    }
}));

const rotas = require('../app/rotas/rotas');
rotas(app);

module.exports = app;

Dúvida: talvez deixei passar alguma explicação neste curso ou nos dos módulos avançados de JS (ou deu um branco/loop geral), porque não entendi a linha de código (como funciona essa ligação/associação entre a const/func rotas e o objeto app): rotas(app);

Complementando, não entendi como é que a func rotas é, posteriormente (durante a execução), chamada "automaticamente", e como ela enxerga o objeto app. Para mim parece que deveria ser algo como:

const rotas = require('../app/rotas/rotas')(app);

Ou seja, que no momento do require o objeto já deveria ser passado por parâmetro, para a const rotas poder ter essa associação entre app e a função rotas em si.

Ou então que, de alguma forma, a const rotas fosse associada ao objeto app (algo como app.algumMetodo(rotas)), ao invés do atual rotas(app).

Desde já obrigado! Atenciosamente.

6 respostas

Elías, boa tarde!

Veja, no arquivo rotas.js nós exportamos uma função, o mesmo aceita um parâmetro que seria o app. Até aí a função não é executada, apenas declarada e exportada.

No arquivo custom-express.js nós salvamos essa função em uma variável chamada rotas

const rotas = require('../app/rotas/rotas');
rotas(app);

O arquivo em si tem acesso ao app pois ele foi declaro algumas linha acima

const app = express();

Sendo assim, nós conseguimos usar a variável para passar como parâmetro da função

rotas(app);

O que ocorre é que ao fazer o require nós só pedimos a função e não executamos ela

Espero ter ajudado e bons estudos!

Olá Felipe!

Obrigado pelo retorno.

Ok, a função é executada e o objeto app é passado como parâmetro.

O que não entendo é como que, posteriormente, essa const/fun rotas e o app continuam associados, e porque a const/func rotas não precisa ser chamada toda vez que o navegador faz uma requisição.

Um exemplo pra ver se eu consigo explicar do porquê de não estar entendendo huahua:

// executando no console do navegador
const app = {titulo: "livros"};
const rotas = (app) => console.log(app);

Se eu chamar a função...:

// ... passando parâmetro
rotas(app) // exibe no console: {titulo: "app"}

// ... sem o parâmetro
rotas() // exibe no console: undefined

Neste exemplo, eu precisaria chamar novamente a const/func rotas e passar o parâmetro novamente para ter o mesmo resultado. Porque no código do node (acima deste exemplo) isso não é necessário (não exibe undefined, nem a const/func rotas precisa ser chamada a cada requisição), e o rotas(app) só precisa ser executado uma vez ?

Atenciosamente.

Elías, bom dia!

Ele só precisa ser chamado uma vez por requisição, o código é interpretado, toda vez que houver uma requisição será criada uma instancia de app.

Existem formas de programar em que a instância será unica, isso nós chamamos de Singleton, mas nesse caso não teria como não passar o app pois a cada requisição é criado uma instância.

Espero ter ajudado e bons estudos!

Olá Felipe!

Obrigado pelo retorno.

Desculpa mas ainda não entendi o rotas(app). Me corrija qualquer coisa: o rotas(app) pelo meu entendimento nada mais é do que uma função recebendo um parâmetro. Como é a que função rotas internamente continua mantendo a referência à variável app? Isso é uma característica do node/express?

Pergunto porque ao criar uma função em JS e passar um parâmetro, o valor desse parâmetro vai ser "esquecido" no término da função... :

const param = "valor";

const exibeValor = function exibeValor(param) {
    console.log(param);
}
exibeValor(param) // exibe "valor" porque é o valor do parâmetro

exibeValor() // exibe: undefined porque não foi passado parâmetro, e a função "esqueceu" o parâmetro recebido na chamada anterior (linha acima).

... já no código rotas(app) com node/express, a função rotas mantém (não esquece) o valor do objeto app, porque, qual é a diferença?

Atenciosamente.

solução!

Elías, boa tarde!

Não se preocupe, Estamos aqui para ajudar! Um ótimo exemplo é o que você está usando:

const param = "valor";

const exibeValor = function exibeValor(param) {
    console.log(param);
}

exibeValor(param); //"Valor"

Veja que mesmo após o método ser executado, nós ainda temos acesso a variável, pois ela se encontra em um escopo acima da função. O parâmetro passado para função, É a mesma variável passada, o que é passado no parâmetro é sua referencia (endereço na memória do computador) e não apenas seu valor.

O rotas é uma função que recebe a referencia de app, e não a variavel app. Tanto isso é real que depois nós usamos o: module.exports = app, pois o app foi alterado dentro de rotas!

Caso tenha encontrado alguma dificuldade não exite em recorrer ao fórum estamos aqui para ajudar

Espero ter ajudado e bons estudo!

Olá Felipe!

Acredito que finalmente entendi (aleluia!):

Em rotas(app), app é passado por referência para a função rotas, porque app é uma função/objeto (nesta forma de atribuição por parâmetro, objetos são atribuídos por referência).

Obs: no meu exemplo (função exibeValor acima), a passagem/atribuição não é por referência, é por valor, porque a var param não é um objeto (é uma string).

Obs2: antes deste tópico, se eu fosse codificar essa parte do código do node com express, considerando as rotas em módulo separado/específico, não sei como iria fazer, mas dificilmente (para não dizer com certeza) passaria pela minha cabeça associar/ligar as rotas (do módulo rotas) com o objeto app (do módulo custom-express) desta forma, ou seja: rotas(app). The Javascript mysteries :o ...

Ajudou sim, muito obrigado pela persistência/retornos!

Atenciosamente.