1
resposta

[JavaScript: programação Orientada a Objetos] [Módulo: 03 - Classes e Herança][Tópico 08: Mão na Massa]

oi pessoal. tudo bem?

seguindo pelos estudos, estou tentando evoluir para o exercício proposto em aula, colocando em prática as classes que estão especificadas no uml do "mão na massa" desta sessão.

Como funcionalidade adicional, estou tentando fazer um gerador de "IDs" únicos para cada novo aluno ingressante, para servir como se fosse num número de matrícula que será registrado como indexador do aluno

Para isso, criei uma função "genarateRandom" que deve fazer a verificação de se o "ID" já existe numa base de dados (criei uma base de dados em txt, só pra praticar) e, em caso negativo, ele cria um novo ID para o aluno ingressante e registra na base de dados:

function generateRandom(){
    
   //lendo o arquivo 'test.txt' , que é o repositório de IDs já criados
   
    fs.readFile('test.txt', 'utf-8', (errrs, repoNumbers) => {
        let idMsg;
        
        //gerando um número aleatório que será o ID de matrícula para os novos alunos
        const randGen = (Math.floor(Math.random()*100).toString()) + "\n";
        if (errrs) throw errrs;
        
        //verificando se o número aleatório que foi gerado já existe na base de dados, em caso positivo, exibo uma mensagem de que usuário já existe, a mensagem é uma das saídas das funções
        
        if(repoNumbers.includes(randGen)){
            idMsg = '***id já existe. por favor, tente gerar um novo ID***';
            return idMsg}
            
        //caso o ID seja válido, ou seja, ele ainda não exista na base de dados, exibo uma mensagem de sucesso, gravo o ID na base de dados e utilizo o valor como saída da minha função.
        
        else{
            fs.appendFile('test.txt', randGen, (error) => {                            
            if (error) throw error;
            idMsg = '*** ID gerado com sucesso ***'
            return idMsg,randGen})

        return (idMsg,randGen)}
    })

    return randGen
        
}
console.log(generateRandom());

Resultado obtido como saída:

    return console.log(idMsg)
                       ^

ReferenceError: idMsg is not defined

Porém, por algum motivo eu não estou conseguindo extrair os valores dos ID's e as mensagens de confirmação ou erro na geração dos IDs. O retorno é sempre um "undefined". Mesmo quando tento fazer um "console.log" na saída, a resposta é indefinida ou que a saída da função não está definida. Alguém consegue me dar uma superforça pra encontrar aonde estou errando?

As saídas de ID, ou seja, o código de matrículo, será utilizada na classe de "User" que está no UML.

1 resposta

Oi Rafael,

Analisando seu código, identifiquei alguns pontos que estão causando o problema do undefined e da dificuldade em obter os valores de ID e mensagens. O principal problema está relacionado ao escopo e à natureza assíncrona da função fs.readFile.

Problema 1: Escopo da variável idMsg

A variável idMsg é declarada dentro do escopo da função callback de fs.readFile. Isso significa que ela não está acessível fora desse escopo, o que causa o ReferenceError: idMsg is not defined quando você tenta usá-la no console.log externo.

Problema 2: Retorno da função generateRandom

A função generateRandom possui um return randGen fora do escopo do fs.readFile. Como a leitura do arquivo é uma operação assíncrona, esse return é executado antes que o callback de fs.readFile seja concluído, resultando em um retorno undefined.

Problema 3: Retorno incorreto dentro do callback

Dentro do callback de fs.readFile, você está usando return idMsg e return idMsg, randGen, que não funcionam como esperado em operações assíncronas. O return dentro do callback não retorna o valor para a função generateRandom, mas sim para o próprio callback.

Solução:

Para corrigir esses problemas, você precisa utilizar Promises ou async/await para lidar com a assincronia e garantir que o valor do ID e a mensagem sejam retornados corretamente. Veja um exemplo usando async/await:

const fs = require('fs').promises;

async function generateRandom() {
    try {
        const repoNumbers = await fs.readFile('test.txt', 'utf-8');
        let idMsg;
        const randGen = (Math.floor(Math.random() * 100).toString()) + "\n";

        if (repoNumbers.includes(randGen)) {
            idMsg = '***id já existe. por favor, tente gerar um novo ID***';
            return idMsg;
        } else {
            await fs.appendFile('test.txt', randGen);
            idMsg = '*** ID gerado com sucesso ***';
            return { idMsg, randGen };
        }
    } catch (error) {
        console.error("Erro ao gerar ID:", error);
        throw error;
    }
}

async function main() {
    try {
        const result = await generateRandom();
        console.log(result);
    } catch (error) {
        console.error("Erro na função principal:", error);
    }
}

main();

Explicação das mudanças:

  1. fs.promises: Importamos fs.promises para usar a versão baseada em Promise das funções do fs.
  2. async/await: A função generateRandom agora é async, permitindo usar await para esperar a conclusão das operações assíncronas.
  3. try/catch: Adicionamos um bloco try/catch para lidar com possíveis erros durante a leitura ou escrita do arquivo.
  4. Retorno do objeto: Retornamos um objeto { idMsg, randGen } quando o ID é gerado com sucesso, para que você possa acessar ambos os valores.
  5. Função main: Criamos uma função main para chamar generateRandom e exibir o resultado.

Para saber mais: JavaScript Async/Await

Com essas mudanças, você deve conseguir obter os valores de ID e as mensagens corretamente. 👍 🤔 💪

Continue praticando e explorando novas soluções!

tux matrix Caso este post o tenha ajudado, marque-o como solucionado ☑️. Bons Estudos! 🤓