Why can’t I use module export to export variable

Asked

Viewed 220 times

0

Explanation:

Good guys in my app.js file have many lines of codic ... Some functions ... But I think it doesn’t matter much, so what I want to do is export a variable that I need to use in another already tried file everything else will not, I tried even in the simplest ways.

What I want to do:

//app.js
token = 'Teste' //Variável que quero exportar
module.exports = {
 token:token
}

And in the file Account.js

//account.js
x = require("./app.js");
console.log(x.token);

Problem: Guys if I test this comic works, however in my project not only has this, I have other functions and imports of lib ... But it doesn’t work ... It always does Undefined.

Another solution I found:

//app.js
token = 'Teste'
exports.token = token

//account.js
x = require("./app.js")
console.log(x.token)

Anyway, it worked, but why didn’t it work out the way I wanted it to? I do not want to use this way just because it works, even because the way I wanted to do works in a file that contains only this snippet, but in my file there is not only this, it has some more functions ... And I don’t know if it affects the way I want to export the variable.

The scenario where I want to apply the first way I want to do:

async function verify(req,res,username,password){              
 db.serialize(async function (){
  const query = 'SELECT * from Users WHERE User = (?) AND Password = (?)'                                                     
  db.all(query,[username, password],async function(err,rows){    
   try{
    if(rows.length == 1){                                          
     console.time("time1")                                         
     await console.log(rows);                                      
     console.log("Correct user");             
     res.render(__dirname + "/View/Home/index.handlebars");        
     module.exports = {
      rows:rows //Desta forma era pra funcionar 
     }                            
     console.timeEnd("time1")                                      
    }                                                        
    else{
    console.log("Incorrect user!")}}
   catch{
    console.error("\x1b[31m","Problema com a função de autenticação, erro: \n", err);
   }
  })
})}

But in my file Account.js:

const express = require('express');
const app = express();                                        
const router = express.Router();                              
const rows = require("./app.js")                              
const io = require('socket.io')                               
const handlebars = require("express-handlebars");             
const multer = require("multer");                             
const path = require("path");

app.engine("handlebars", handlebars({defaultLayout:false}));
app.set("view engine","handlebars");                         
app.get('/',(req,res) => {                                    
 res.render(__dirname + "/View/Account/account.handlebars")
 console.log(rows.rows);
 //Quando eu entrasse nessa rota eu queria que aparecesse o valor da variável da forma que eu queria exportar como havia explicado
});

module.exports = app

Type of error: Undefined

There are more things in my app.js file but I only put the function where I want to use the export module.

  • There is nothing wrong with any of your codes. They all work correctly (except the quotation marks at the end of x.token), but I think it was an accident during the question. Anyway, try to create a [mcve] and bring it here. No need to include whole your file, just try reproduce what is not working (because currently the question is "ok").

  • Yes it was an accident I will edit, but I also saw that it’s okay when you test only this way but my app.js and Account.js is much bigger than what I showed and maybe it interferes you think I should post all the files' comic here? Because the original comic is big

  • I edited as recommended :)

  • @William you are giving the export inside the Verify function that is not even being called, maybe performing her call at the end of the file works, but you are doing at least something peculiar, calling the export inside an asynchronous function, maybe it would not be better to export the function that returns this data and then use in Account.js?

  • It is being called only showed where I tried to use, but the problem is that when I call the function of Undefined was not to happen this.

  • And I can’t export function pq I won’t use function only variable.

Show 1 more comment

3 answers

0

The context is somewhat confused, but I believe the error is in the asynchronous function.

The function verify that you created is an asynchronous function, but the reserved word await is at the beginning of console.log(...). So when you export the variables, they may not have had time to be generated.

the await should come before a Promise, as for example before db.all(....) that will make a query in the database.

  • console.log is not asynchronous,

0


Apparently, what you want is to keep some variables for a specific user between requests, if this is the case, you should use sessions.

take a look at the express-Session npm package, it might satisfy you:

https://www.npmjs.com/package/express-session

Exports is a variable equivalent to global in the scope of the function you run...it is not recommended to use global variables for storing variables that depend on user to user, they will overwrite each other

or

if the question is not is, but simply returns the ROW value from within the Verify function I advise you to refactor it to use Promise, I decided to refactor and left some comments:

//removi o parametro req pós não é utilizados
function verify(res,username,password){
    return new Promise((resolve,reject)=>{
        //não precisa de async, pós não há await dentro
        db.serialize(function (){
            const query = 'SELECT * from Users WHERE User = (?) AND Password = (?)'
            //não precisa de async, pós não há await dentro
            db.all(query,[username, password],function(err,rows){
                try{
                    if(rows.length == 1) {
                        console.time("time1");
                        //console.log não é uma função assincrona, não precisa de await
                        console.log(rows);
                        console.log("Correct user");
                        res.render(__dirname + "/View/Home/index.handlebars"/*, objeto com variaveis para o handlerbars*/);
                        //não retorne a variavel pelo exports, exports é um globlal
                        //em um ambiente com varias requisições, passar as respostas de varias requisições por uma global não é nada recomendado, pós entre o tempo de definila e finalizar e retorna, ela já pode ter sido sobreescrita por outra requisição      
                        //isso ira retorna pelo await...;
                        resolve(rows);
                        console.timeEnd("time1")
                    } else {
                        console.log("Incorrect user!");
                        //adicionei um res.send, pós se a requisição nunca chamar res.send, o browser ira aguarda até gerar um erro "timeout" pós, nenhuma respostas foi enviada
                        res.send("Incorrect user!");
                    }
                } catch (e){
                    res.send("Problema com a função de autenticação");
                    console.error("\x1b[31m","Problema com a função de autenticação, erro: \n", err);
                }
            }
        });
    });
}

*Obs.: because I didn’t know the DB API used, I didn’t add the cases where the query goes wrong (which may also be a reason Row never be set)...

  • So ...the variable can be overwritten by another request, but what I want to do is export the Rows variable to my Account.js file that will go through the array and get the user id, to search for a photo that has this name (that will be the user id) and upload this photo to the Account page, but for this I need to export the variable so log in only I need to resolve this in the question of the variable being overwritten, could you give me a guide ? 'Cause I’ve had this problem for a while

  • @Guilherme, you will go through function/return parameters if you can do this in single request (which is recommended)..., and if you will search per user in specific, it is also recommended to do this in query, do this in Node js, will increase the consumption of RAM and Network quite unnecessarily

  • @William the Verify function as it is in the answer returns the Rows; Obs: the "res.send" can only be called once, I recommend that you o-do na only in the Narrow Function that is in the get, to avoid several "res.send" scattered by several files...that can make the code more difficult to find bugs; ah, to get the return of the Verify function in get, you use then(). catch, or change the Narrow Function declaration, from "(req,res) => {" to "async (req,res) => {", and use await Verify(...

  • @Guilherme as for the user profile photo, if it does not need to be private, you can simply save it in a static content public folder, and use some unique property as user id as name...; ah and if you are making a system with logins; you will need sessions; look at the express-Session link; and search for logins and sessions on Node-js, it’s very common tutorials on sessions/logins over the internet, for any platform

  • Yes, I save the user id as the name of the photo, but I need to upload a certain photo to certain users, but when I log in and go to Index, and the photo that should be uploaded should be uploaded to the Account page, but how do I know which photo should be uploaded to a particular user? As much as I have saved the id as the name of the photo I need the id of the user who is accessing the route to fetch his photo, and how to get the id of the user if not exporting? Why my Account page is accessed on the Account route.

  • I thought the following solution to my problem, the user log in, I save this id in the cookie and when accessing the Account route, I create a function to read the value of the cookie capturing the id, and knowing the id then fetch the photo and load, but this solution is not so elegant since I saw a post with a different way of doing but there is only step by step in theory has no practice and was using database so I do not know apply and if it is possible otherwise than this.

  • @William, you need sessions, sessions are like server-side cookies! read about sessions/logins...as I recommended, sessions is a trivial "subject" for server logins

  • as your last comment suggested, you will be saved in the "cookie", but in the "server cookie", in the session... this is how it is usually done, good luck

Show 3 more comments

-1

if your Node JS does not support ES6 (version earlier than 10), the error is this:

module.exports = {
 token:token
}
//que pode ser
module.exports = {
 token
}
//ou
module.exports = {
 'token':token
}

when doing token:token, it creates an object with a variable that has both the name and the value equal to 'Test', if you do not want to put a new name to the variable, just put it, if you want to give a new name inside the object, to prevent the value of another variable from being used as a key, use a string to prevent the value of another variable from being used as a name within the object

'novoNome':token,

This is one of the features that before ES6 made Java script easy to write and hard to break..., which can sometimes leave you confused.

OBS.: if the name of the variable inside the object were not a defined variable it would work...

  • Actually this is not wrong, this more simplistic form was introduced in ES6 and is called "Object Property Value Shorthand", if you want to know more you can see here: https://alligator.io/js/object-property-shorthand-es6/

  • @Victornogueira, but until Node js 10, ES6 does not exist or is experimental, and until late last year, Node js 8 was still used in production by google for example (firebase), which took out Node js 8 support and added support to 12, newer versions of Node JS are out...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.