Como criar eventos JavaScript customizados

Criar eventos customizados no JavaScript é bem simples e pode ser feito em poucas linhas. O importante é termos os seguintes passos:

  • Criação de um objeto usando new Event
  • Atribuição de um listener a um elemento
  • Chamada ao método que disparará o evento criado e vinculado a aquele elemento.
// Criando o nosso evento
const meuEvento = new Event("meuNovoEvento");

// Atruibuindo o listener ao document mesmo para o exemplo ficar pequeno
document.addEventListener("meuNovoEvento", e => console.log(e))

// executando o evento para o elemento document.
document.dispatchEvent(meuEvento);

Basicamente é isso, abaixo eu gostaria de falar sobre alguns pontos importantes para você entender o que aconte por baixo do panos.

Sincrono ou Assincrono?

Segundo site do mozilla “Ao contrário dos eventos “nativos”, que são disparados pelo navegador e invocam manipuladores de eventos de forma assíncrona por meio do loop de eventos, dispatchEvent() invoca manipuladores de eventos de forma síncrona. Todos os manipuladores de eventos aplicáveis ​​são chamados e retornados antes do retorno de dispatchEvent().”

Modificando as propriedades do Evento

Se você executou o evento acima você deve ter visto no console que aparecem várias propriedades para o evento. Algumas uteis, outras apenas se você está querendo criar algo extremamente complexo.

Vamos falar de algumas delas

  • isTrusted: Será true quando o evento foi disparado por uma interação do usuário e false quando algum código JavaScript o fez.
  • bubbles: Determina se a aplicação fará o bubbling pelo DOM
  • cancelable: Informa se o elemento pode ser cancelado pelo comando e.preventDefault()
  • target: O elemento que sofreu a ação.
  • currentTarget: Normalmente é o mesmo que objeto que o target a não ser que tenha ocorrido algum redirecionamento.
  • type: O tipo, o nome do nosso elemento.

Então era isso, caso você tenha interesse em aprofundar os seus conheicmentos eu recomendo dar uma lida na documentação oficial que você pode acessar por este link https://developer.mozilla.org/en-US/docs/Web/API/Event

Como usar JavaScript no Oracle APEX

O que é o Oracle APEX?

Para aqueles que não conhecem, o Oracle APEX é uma plataforma gratuita de desenvolvimento low code disponibilizado pela Oracle e que você pode testar tanto criando uma conta https://apex.oracle.com/, criando direto em cima de uma banco oracle em sua maquina quanto instanciando na nuvem.

Se você nunca mexeu nele, então eu recomendo começar pelo link que passei para ver se a plataforma atende as necessidades e pelo simples fato de ser mais rapido de fazer tudo funcionar.

Imagem do Dashboard do APEX
Dashboard do APEX

Nossas postagens sobre APEX

Veja aqui mais postagens nossas sobre o tópico: https://www.mundojs.com.br/tag/apex/

Onde o JavaScript se encaixa nisso?

Caso você ja tenha acessado o link ou acessou antes de continuar lendo você deve estar se perguntando, onde o JavaScript vai ser usado aqui? Se eu colocar JavaScript não vou estar deixando de usar a plataforma da forma correta?

Como muito pode ser feito sem programar e sem intervenção direta de código, eu espero que você tenha feito essas perguntas, pois elas são importantes.

A resposta é simples, você pode sim trabalhar com o Javascript usando a API JavaScript disponibilizada e pode fazê-lo em múltiplos níveis.

Por exemplo, coisas como

// caixas de mensagem
apex.message.alert(texto);
apex.message.confirm(texto, funcaoCallback);

// definir valores
apex.item(identificador).setValue(valor)

// chamadas AJAX
apex.server.process(nomeProcess, dadosEnviados, funcaoCallback);

Podem ser feitas com funcionalidades (blocos lógicos) low code como

  • alert
  • confirm
  • set value
  • execute server side code, set value ou refresh

Mesmo assim, é importante que saber que temos opções que recebem suporte e que estão disponíveis na API. por isso acho importante evitar código que modele/acesse diretamente as propriedades como

// caixas de mensagem
alert(texto)
confirm(texto)
$( seletor ).dialog();

// definir valores
document.querySelector(seletor).value = valor;
$(selector).val(valor)

// chamadas AJAX
fetch(url, opcoes)
$.ajax(url);

Por mais que estes métodos funcionem, ja me deparei com casos que o framework (não só no APEX) mudou e com isso a funcionalidade deixou de acontecer ou teve um comportamento inesperado. Problemas como

  • seletores mudarem dentro do framework
  • links serem ajustados
  • componentes complexos serem reestruturados

Entre outras opções são comuns com o crescimento das plataformas, especialmente quando elas usam conjuntos de ferramentas de suporte.

Conclusão

Essa foi uma postagem rápida tentando falar um pouco da melhor forma de trabalhar como um desenvolvedor front end no APEX e mostrar algo, que na minha opinião, é muito importante e precisa ser feito com basntate estudo e atenção

Como funciona o Intl.NumberFormat?

Neste breve post veremos como funciona o Intl.NumberFormat em partes para entendê-lo melhor e podermos gerar várias strings com valores numéricos formatados corretamente.

Sintaxe

A sintaxe básica é bem simples, instanciamos um objeto que precisa de dois parametros, locales e options. Ambos são opcionais

new Intl.NumberFormat([locales[, options]])

locales: em 99% dos casos nós usaremos as strings com representação do local/país/região representada no nosso objeto. Você provavelmente usará os valores ‘pt-BR’, ‘en’ ou alguma variação parecida. Para um guia completo, confira aqui: https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry

const valor = 1999.99;
console.log(new Intl.NumberFormat('pt-BR').format(valor));
// saida: 1.999,99
console.log(new Intl.NumberFormat('ar-EG').format(valor));
// saida: ١٬٩٩٩٫٩٩

options: O segundo parâmentro é um pouco mais complicado pois as opções tem várias opções… kkkk… mas faz parte Vejamos um modelo e depois explicarei o que cada coisa faz

const valor = 1999.99;

const options = {
    style : "currency",
    currency : "BRL",
    minimumIntegerDigits : 10,
    minimumFractionDigits : 2,
    maximumFractionDigits: 5,
}

console.log(new Intl.NumberFormat('pt-BR', options).format(valor));
// saida: R$ 0.000.001.999,99

style:

Definição: O estilo do formato a ser utilizado.

Valor Padrão: “decimal”

Valores Permitidos: “decimal" para formato de número simples, "currency" para formato monetário e "percent" para formato percentual;

currency:

Definição: A moeda para usar na formatação monetária.

Valor Padrão: Não existe. Se o style for “currency”, então o esta propriedade precisa ser informada

Valores Permitidos: Os valores permitidos são os códigos de moedas da ISO 4217, como "USD" para dólar estadunidense, "EUR" para euro, ou "CNY" para RMB chinês — veja a Lista de códigos de moedas e fundos atuais.

minimumIntegerDigits

Definição: A quantidade mínima de dígitos inteiros para utilizar.

Valor Padrão: 1

Valores Permitidos: de 1 a 21

minimumFractionDigits

Definição: A quantidade mínima de dígitos fracionados para utilizar.

Valor Padrão: o padrão para formatos monetários é a menor unidade de dígitos fornecidos pela lista de códigos de moedas ISO 4217 (2 se a lista não fornecer a informação).

Valores Permitidos: de 0 a 20.

maximumFractionDigits

Definição: O número máximo de dígitos fracionados para utilizar

Valor Padrão: o padrão para a formatação de número simples é o maior entre minimumFractionDigits e 3.

Valores Permitidos: de 0 a 20.

CONCLUSÃO

Isso pessoal, esse foi um tutorial bem simples de como usar uma classe extremamente útil. Para mais detalhes, vejam também a documentação oficial https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat

Como usar o forEach no JavaScript

forEach

Neste breve artigo, estarei mostrando como usar o forEach no JavaScript usando todas as possibilidades de passagem de valores no exemplos. Estarei presumindo que você entende como funcionam Arrays e Arrow Functions.

Descrição e uso do forEach

O forEach é um método acessado dos objetos array (vetores) que itera entre todos os itens da lista executando uma função que informamos passada por parâmetro. Sendo assim, quando você possui uma coleção que precisa ser iterada ele é um ótimo candidato por ser sucinto e fácil de entender.

Quando não usar o forEach

Se você precisa parar a iteração, o forEach não é o melhor candidato. Ele não é um loop que podemo encerrar com ‘break’ e se na função de callback colocarmos um ‘return’, ele simplesmente seguirá para o próximo item. Neste tipo de situação, de preferencia para os loops tradicionais.

Array.forEach simples

a forma mais simples é chamando o método e passando uma função de callback que possui apenas um parâmetro

// Uma lista simples
const dados = [1,2,3,4,5,6,7,8];
// uma função de callback com apenas 1 item passado de parametro
const callback = item => console.log(item)
// a chamada
dados.forEach(callback);

Poderíamos colocar a função diretamente dentro da chamada

dados.forEach(item => console.log(item));

Ou chamar todo o primeiro exemplo em apenas 1 linha

[1,2,3,4,5,6,7,8].forEach(item => console.log(item));

Mas é importante tentar manter o seu código o mais fácil de entender possível.

Array.forEach com 2 parâmetros no callback

Digamos que você precise saber o índice do item por algum motivo, neste caso, precisamos informar mais um parâmetro em nossa callback. Vamos fazer um exemplo um pouco diferente

// Uma lista com strings para não confundir com o valor do indice
const dados2 = ['caixa', 'pallet', 'caixote', 'sacola', 'avulo'];
// A callback agora precisa de um segundo parametro 
const callback2 = (item, indice) => console.log(`${indice}: ${item}`)
// mesma chamada
dados2.forEach(callback2);

Ao executar o código você verá que teremos a posição dos items e seus valores. Para comparação, o For tradicional geraria este Loop da seguinte maneira:

for(let indice; indice < dados2.length; indice++) console.log(`${indice}: ${item}`)

Array.forEach com 2 parâmetros

Para este exemplo, manteremos o nosso segundo vetor

const dados2 = ['caixa', 'pallet', 'caixote', 'sacola', 'avulo'];

e vamos criar um objeto bem simples com apenas 1 função que executa um console log no valor passado por parametro, no mundo real seria somente uma função, mas para nosso exemplo ele ele vale.

let obj = { log : (umItem) =&gt; console.log(umItem)}

Agora, se você quisesse executar o obj.log para cada item do dados2, você poderia fazer algo assim:

dados2.forEach(item =&gt; obj.log(item));

e vai funcionar. Agora digamos que você tenha uma ambiente dinamico no qual você não sabe o qual objeto está executando o método log e dentro deste método poderiam acontecer coisas diferentes ou até que você está montando uma biblioteca que receberá o objeto e executará alguma coisa. Como você faria? Com o forEach, é possível fazer o seguinte

dados2.forEach(item =&gt; this.log(item), obj);

Deu erro? Isso é porque arrow function não podem receber escopo, se não entendeu, veja novamente o link Arrow Functions. Entendeu, então a parte abaixo é simples. A solução mais simples, use a função normal.

dados2.forEach(function(item){ this.log(item)}, obj);

Era isso, espero que tenham gostado, qualquer duvida deixem nos comentários.

Atualizações do site

logo

Olá pessoal, já faz um tempinho que não postamos este tipo de boletim informativo. Mas com todas as coisas que aconteceram nestes últimos 2 anos infelizmente o MundoJS acabou ficando um pouco parado.

Bom, o plano é retomar as atividades aos poucos , demos uma olhada e o que a galera mais tem gostado é de dicas sobre os fundamentos do JS, então vamos começar por lá. Criar tutorais de como fazer as coisas e também focar talvez em vídeos.

Eu costumo a escrever no plural, mas na verdade voltou a ser uma equipe de uma pessoa. O que faz parte… kkkkkk

Como vocês devem ter visto o site ta com outra cara, isso porque, para os próximos meses

foco será:

  • Novos posts com tutorais
  • Focar na velocidade do site
  • Melhorar a performance e segurança do site
  • Aumentar o conteúdo em vídeo
  • Remover as coisas que ninguém, ou quase ninguém, está usando.

O que já fiz nos últimos dias

  1. Novo layout, muito mais leve.
  2. Removido a funcionalidade de push de notificações. Tinha apenas umas 30 pessoas usando ele.
  3. Atualizado o Site, plugins de segurança.
  4. Removido plugins de antigos que a atualização invalidou… Quebrou quase nada.. kkk
  5. Iniciado novas postagens

Por último o plano para o futuro é

  • Continuar postando
  • Criar vídeos
  • Melhorar a área de cursos
  • Criar enquetes e buscar mais gente para contribuir

Extreme Go Horse – Gambiarra é para os fracos

extreme-go-horse

Conheça a metodologia Extreme Go Horse (XGH) onde você não precisa perder tempo com padrões, pensamento, documentação ou qualquer bobagem que vai te fazer produzir código. Aqui você sempre programa 8 mil linhas de código por segundo e se você teve que parar para pensar em fazer uma gambiarra, você lento e não sabe o que ta fazendo… kkkkkk… Bom, chega de enrolar, veja a baixo como funciona

1- Pensou, não é XGH.

XGH não pensa, faz a primeira coisa que vem à mente. Não existe segunda opção, a única
opção é a mais rápida.

2- Existem 3 formas de se resolver um problema, a correta, a errada e a XGH, que é igual à errada, só que mais rápida.

XGH é mais rápido que qualquer metodologia de desenvolvimento de software que você
conhece (Vide Axioma 14).

3- Quanto mais XGH você faz, mais precisará fazer.

Para cada problema resolvido usando XGH, mais uns 7 são criados. Mas todos eles serão
resolvidos da forma XGH. XGH tende ao infinito.

4- XGH é totalmente reativo.

Os erros só existem quando aparecem.

5- XGH vale tudo, só não vale dar o toba.

Resolveu o problema? Compilou? Commit e era isso.

6- Commit sempre antes de update.

Se der merda, a sua parte estará sempre correta.. e seus colegas que se fodam.

7- XGH não tem prazo.

Os prazos passados pelo seu cliente são meros detalhes. Você SEMPRE conseguirá
implementar TUDO no tempo necessário (nem que isso implique em acessar o BD por um
script malaco).

8- Esteja preparado para pular fora quando o barco começar a afundar… ou coloque a culpa em alguém ou algo.

Pra quem usa XGH, um dia o barco afunda. Quanto mais o tempo passa, mais o sistema
vira um monstro. O dia que a casa cair, é melhor seu curriculum estar cadastrado na
APInfo, ou ter algo pra colocar a culpa.

9- Seja autêntico, XGH não respeita padrões.

Escreva o código como você bem entender, se resolver o problema, commit e era isso.

10- Não existe refactoring, apenas rework.

Se der merda, refaça um XGH rápido que solucione o problema. O dia que o rework
implicar em reescrever a aplicação toda, pule fora, o barco irá afundar (Vide Axioma 8).

11- XGH é totalmente anárquico.

A figura de um gerente de projeto é totalmente descartável. Não tem dono, cada um faz o
que quiser na hora que os problemas e requisitos vão surgindo (Vide Axioma 4).

12- Se iluda sempre com promessas de melhorias.

Colocar TODO no código como uma promessa de melhoria ajuda o desenvolvedor XGH a
não sentir remorso ou culpa pela cagada que fez. É claro que o refactoring nunca será
feito (Vide Axioma 10).

13- XGH é absoluto, não se prende à coisas relativas.

Prazo e custo são absolutos, qualidade é totalmente relativa. Jamais pense na qualidade e
sim no menor tempo que a solução será implementada, aliás… não pense, faça!

14- XGH é atemporal.

Scrum, XP… tudo isso é modinha. O XGH não se prende às modinhas do momento, isso é
coisa de viado. XGH sempre foi e sempre será usado por aqueles que desprezam a
qualidade.

15- XGH nem sempre é POG.

Muitas POG’s exigem um raciocínio muito elevado, XGH não raciocina (Vide Axioma 1).

16- Não tente remar contra a maré.

Caso seus colegas de trabalho usam XGH para programar e você é um coxinha que gosta
de fazer as coisas certinhas, esqueça! Pra cada Design Pattern que você usa corretamente,
seus colegas gerarão 10 vezes mais código podre usando XGH.

17- O XGH não é perigoso até surgir um pouco de ordem.

Este axioma é muito complexo, mas sugere que o projeto utilizando XGH está em meio ao
caos. Não tente por ordem no XGH (Vide Axioma 16), é inútil e você pode jogar um tempo
precioso no lixo. Isto fará com que o projeto afunde mais rápido ainda (Vide Axioma 8).
Não tente gerenciar o XGH, ele é auto suficiente (Vide Axioma 11), assim como o caos.

18- O XGH é seu brother, mas é vingativo.

Enquanto você quiser, o XGH sempre estará do seu lado. Mas cuidado, não o abandone. Se
começar um sistema utilizando XGH e abandoná-lo para utilizar uma metodologia da
moda, você estará fudido. O XGH não permite refactoring (vide axioma 10), e seu novo
sistema cheio de frescurites entrará em colapso. E nessa hora, somente o XGH poderá
salvá-lo.

19- Se tiver funcionando, não rela a mão.

Nunca altere, e muito menos questione um código funcionando. Isso é perda de tempo,
mesmo porque refactoring não existe (Vide Axioma 10). Tempo é a engrenagem que move
o XGH e qualidade é um detalhe desprezível.

20- Teste é para os fracos.

Se você meteu a mão num sistema XGH, é melhor saber o que está fazendo. E se você
sabe o que está fazendo, vai testar pra que? Testes são desperdício de tempo, se o código
compilar, é o suficiente.

21- Acostume-se ao sentimento de fracasso iminente.

O fracasso e o sucesso andam sempre de mãos dadas, e no XGH não é diferente. As
pessoas costumam achar que as chances do projeto fracassar utilizando XGH são sempre
maiores do que ele ser bem sucedido. Mas sucesso e fracasso são uma questão de ponto
de vista. O projeto foi por água abaixo mas você aprendeu algo? Então pra você foi um
sucesso!

22- O problema só é seu quando seu nome está no Doc da classe.

Nunca ponha a mão numa classe cujo autor não é você. Caso um membro da equipe
morra ou fique doente por muito tempo, o barco irá afundar! Nesse caso, utilize o Axioma
8.

Smart Mask – Máscara de Dados

Precisando de uma máscara de CPF, CNPJ ou entre outras?

Smart Mask (https://github.com/pkunzel/smart_mask) é uma biblioteca de máscara de dados bem simples com o intuito de fornecer múltiplas mascaras que com frequencia com frequência em um sistema ou app. O Projeto é constituído por duas classes, uma que aplica as máscaras e outra que monitora elementos HTML para manter a máscara aplicada. 

Como funcionam as classes? 

ApplyMask 

A Classe apply mask possui apenas métodos estáticos que estão prontos para serem chamados mediante passagem de parâmetros conforme exemplo abaixo 

ApplyMask.toCPF('88888888888') 
// output '888.888.888-88' 

ApplyMask.toPhone('51999999998') 
// output '(51) 999999998'

ApplyMask.charactersOnly('qwerty12345') 
// output 'qwerty' 

CustomMask

Gera eventos para os elementos com o atributos data-custom-mask=”mascara”, onde máscara é o nome do tipo de máscara a ser implementada. As opções são 

• cpf: um CPF 

• cnpj: um CNPJ 

• phone: um telefone com DDD incluso 

• cep: um CEP 

• date: uma data seguindo o formato DD/MM/YYYY 

• numbers: extrai apenas os valores numéricos 

• characters: extrai apenas os caracteres 

• non-special-characters: Extrai apenas os caracteres não especiais 

Exemplo 

HTML 

<input type="text" data-custom-mask="cpf" value="11122233344" /> 

JS 

// Ao iniciar a página 

window.addEventListener('load', (e) => new CustomMask()); 

// Obs.: Pode ser feito inicializado em qualquer outro momento. 

Importante: Qualquer valore que seja maior que o tamanho da máscara terá os últimos caracteres removidos. ou seja, um CPF que venha com 15 caracteres devido a algum erro terá os últimos 4 caracteres removidos.

Conheça SvelteJS, um framework Frontend JavaScript

O Svelte é um framework com uma nova maneira de desenvolver interfaces de usuário. Frameworks tradicionais como React e Vue fazem a maior parte do trabalho no browser, o Svelte realiza esse trabalha em uma etapa de compilação que acontece quando você constrói a sua aplicação.

Sem utilizar técnicas como virtualização do DOM, o Svelte escreve código que cirurgicamente atualiza o DOM quando o estado do seu app muda. A diferença crucial entre o Svelte e outros frameworks JavaScript é que o Svelte converte o seu app para JavaScript ideal em tempo de construção, ao invés de interpretar seu código em tempo de execução. Isso significa que você não terá que considerar custo de performance das abstrações do framework, e você não terá penalidades quando seu app carregar pela primeira vez.

Você pode escrever o seu aplicativo do zero utilizando o Svelte, ou pode adicioná-lo de forma incremental à uma base de código já existente. Você também pode utilizar componentes como pacotes independentes, que funcionam em qualquer lugar, sem a sobrecarga de dependências de um framework convencional.

Componentes

No Svelte, uma aplicação é composta de um ou mais componentes. Um componente é um bloco de código reutilizável que encapsula HTML, CSS e JavaScript juntos em um arquivo .svelte.

Por exemplo:

<script>
    let nome = "mundo";
</script>

<h1> Olá Mundo!</h1>

E podemos utilizar uma referência à variável nome, criada acima!

<h1>Olá {nome}!</h1>

E isso nos trará o resultado:

Olá mundo!

Também podemos armazenar caminhos de url e pastas de armazenamento em variáveis, e utilizá-las em atributos de nossos elementos HTML, como:

<script>
    let caminhoOrigem = "imagem/foto.png";
</script>

<img src={caminhoOrigem}>

E isso funcionará. Mas o Svelte nos trará uma mensagem:

A11y: <img> element should have an alt attribute

Quando estamos criando web apps, é importante ter certeza que ele será acessível para todos os usuários, e isso inclui pessoas com dificuldades de visão ou movimento, ou até mesmo pessoas com boa conexão à internet e com bom hardware. A acessibilidade é de extrema importância no desenvolvimento e o Svelte auxilia avisando-o se você não escreveu elementos de marcação acessíveis.

Nesse caso, teremos:
<img src={caminhoOrigem} alt="Seu texto acessível aqui.">

Você pode fazer o download do Svelte diretamente no site em um arquivo .zip ou utilizando o npm e npx:

npx degit sveltejs/template my-svelte-project

cd my-svelte-project

npm install

npm run dev

Você pode verificar a documentação em: https://svelte.dev/tutorial/basics

Gostou deste artigo? Comente abaixo!

Referência: https://svelte.dev/

Princípios do SOLID com TypeScript – SRP

Veja nesse artigo uma rápida introdução ao SOLID e um exemplo prático sobre o SRP (Principio da responsabilidade unica) utilizando TypeScript

Introdução

Fala galera tudo bem? Aproveitando que estamos iniciando uma serie de podcasts sobre os princípios do SOLID no nosso canal DEVSHOW.

  • O (OCP) Princípio Aberto-Fechado
  • L (LSP) Princípio da Substituição de Liskov
  • I (ISP) Princípio da Segregação da Interface
  • D (DIP) Princípio da inversão de dependência

Principio da Responsabilidade Única (SRP)

Esse é o primeiro principio e na minha opinião o mais simples e o mais importante, ele diz que uma classe deve ter apenas um motivo para mudar” ou sejadeve ter apenas uma responsabilidade. Caso a sua classe tenha mais de uma razão para mudar, ela está fazendo mais de uma coisa, logo quebrando esse principio.

import * as express from "express";
import * as bodyParser from "body-parser";
import * as nodemailer from "nodemailer";
import config from '../config/configs';


class App {

    public app: express.Application;

    constructor() {
        this.app = express();
        this.app.use(bodyParser.json());
        this.routes();
    }
    routes() {

        this.app.route("/").get((req, res) => {
            res.send({ 'result': 'version 0.0.2' })
        });

        this.app.route("/").post((req, res) => {
            const message = Object.assign({}, req.body);
            let result = this.sendMail(message.to, message.subject, message.message);
            res.status(200).json({ 'result': result })
        });
    }


    sendMail(to?: string, subject?: string, message?: string) {

        let mailOptions = {
            from: "",
            to: to,
            subject: subject,
            html: message
        };

        const transporter = nodemailer.createTransport({
            host: config.host,
            port: config.port,
            secure: false,
            auth: {
                user: config.user,
                pass: config.password
            },
            tls: { rejectUnauthorized: false }
        });

        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                return error;
            } else {
                return "E-mail enviado com sucesso!";
            }
        });
    }
}

export default new App();
  • O método de envio de e-mail deveria estar em uma outra classe separada
import * as nodemailer from "nodemailer";
import config from './config/configs';

class Mail {

    sendMail(to?: string, subject?: string, message?: string) {

        let mailOptions = {
            from: "",
            to: to,
            subject: subject,
            html: message
        };

        const transporter = nodemailer.createTransport({
            host: config.host,
            port: config.port,
            secure: false,
            auth: {
                user: config.user,
                pass: config.password
            },
            tls: { rejectUnauthorized: false }
        });

        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                return error;
            } else {
                return "E-mail enviado com sucesso!";
            }
        });
    }

}

export default new Mail;
import * as express from "express";

const indexRouter = express.Router();

indexRouter.route("/").get((req, res) => {
    res.send({ 'result': 'version 0.0.3' })
});

export default indexRouter;

emailRouter.ts

import * as express from "express";
import mail from "../mail";

const emailRouter = express.Router();

emailRouter.route("/").post((req, res) => {
    const message = Object.assign({}, req.body);
    let result = mail.sendMail(message.to, message.subject, message.message);
    res.status(200).json({ 're sult': result })
});

export default emailRouter;

E por fim atualizamos o arquivo app.ts com o seguinte trecho de código:

import * as express from "express";
import * as bodyParser from "body-parser";
import indexRouter from "../router/indexRouter";
import emailRouter from "../router/emailRouter";


class App {
    public app: express.Application;

    constructor() {
        this.app = express();
        this.app.use(bodyParser.json());
        this.routes();
    }
    routes() {     
        this.app.use("/", indexRouter);
        this.app.use("/", emailRouter);      
    }
}

export default new App();

Gostou deste artigo? Comente abaixo!

Referência: https://programadriano.medium.com/princ%C3%ADpios-do-solid-com-typescript-1e585c6eeb5e

Princípios do SOLID com TypeScript – OCP

Veja nesse artigo um exemplo prático do principio OCP — Princípio Aberto-Fechado

Introdução

Dando continuidade a minha série de artigos sobre os princípios do SOLID com TypeScript e aproveitando a liberação do episódio 2 do nosso podcast: DevShow #22 SOLID OCP. Hoje irei abordar o segundo principio do SOLID, OCP.

Image for post

enum TipoDeArquivo {
    pdf,
    excel
}


class Arquivos {
    Exportar(arquivo: TipoDeArquivo, data: any) {

        if (arquivo == TipoDeArquivo.excel) {
            // exportar data para excel
        }

        if (arquivo == TipoDeArquivo.pdf) {
            // exportar data para pdf
        }
    }
}
enum TipoDeArquivo {
    pdf,
    excel,
    word
}


class Arquivos {
    Exportar(arquivo: TipoDeArquivo, data: any) {

        if (arquivo == TipoDeArquivo.excel) {
            // exportar data para excel
        }

        if (arquivo == TipoDeArquivo.pdf) {
            // exportar data para pdf
        }

        if (arquivo == TipoDeArquivo.word) {
            // exportar data para word
        }

    }
}
abstract class Arquivos {
    Exportar(data: any) { }
}


class GerarExcel extends Arquivos {
    Exportar(data: any) {

    }
}

class GerarPDF extends Arquivos {
    Exportar(data: any) {

    }
}

class GerarWord extends Arquivos {
    Exportar(data: any) {

    }
}

Gostou deste artigo? Comente abaixo!

Referência: https://programadriano.medium.com/princ%C3%ADpios-do-solid-com-typescript-2c6a4911242d