DEV Community

Ryan Monteiro
Ryan Monteiro

Posted on

Quanto vale as suas milhas?

Você já tentou usar suas milhas para comprar algum produto ou serviço porém não teve a certeza de que aqueles valores em milhares valiam realmente a pena? Pois é, eu sempre me sinto assim, e hoje resolvi criar uma simples função no console do meu navegador para resolver essa questão. E como utilizei diversos contextos e APIs nativas não tão difundidas, resolvi fazer esse artigo para ajudar quem mais estiver precisando.

Esse tutorial espera que entenda o básico de programação web, como saber utilizar o DevTools e navegar pela árvore de elementos HTML.

Passo a passo

1. Buscar característica comum entre os elementos

Já no site onde os produtos estão sendo apresentados com os valores em milhas, vamos buscar alguma característica em comum entre eles. Ao olhar os elementos através do Inspecionar Elemento (Ctrl + Shift + C) e selecionar alguns que possuem as contagens de pontos observamos que na árvore de elementos todos eles possuem a classe price
Descrição dos atributos de um elemento HTML

2. Selecionar elementos de pontos

Então para selecionar todos os elementos da página que possua esse atributo basta utilizar algum seletor de elementos que o javascript nos oferece. Normalmente se utiliza o clássico document.querySelector para encontrar somente um elemento ou document.querySelectorAll que retorna uma lista de elementos. Porém, nesse tutorial quero apresentar a vocês o simples $$ que existe somente no seu DevTools. Ele possui a mesma função do selectorAll e fica menos verboso.
E então escrevemos no console de nossa página a função $$ passando como parâmetro o identificador CSS dos elementos que armazenam o preço em pontos.

$$('span.price')
Enter fullscreen mode Exit fullscreen mode
// Output
[span.price, span.price,span.price,span.price,span.price,span.price, ...]
Enter fullscreen mode Exit fullscreen mode

Ao rodar esse código, esperamos que o console nos retorne um array com todos os elementos html que sejam um elemento <span class="price"

3. Buscando os valores de pontos de cada produto

Como a nossa função nos retorna um array podemos utilizar todas as funções dessa classe, como map, forEach , sendo que aquela modifica os elementos e nos retorna um novo array, e essa executa algo para cada elemento sem retornar nada.
Para encontrar o texto de um elemento HTML, podemos utilizar duas propriedades. a innerHTML que nos retorna todo o conteúdo html de um elemento, ou a innerText que nos retorna o conteúdo já convertido para texto. Como queremos somente o texto, vamos utilizar a segunda.

$$('span.price').map((el) => {
    return el.innerText
})
Enter fullscreen mode Exit fullscreen mode
// Output
["74.377 pontos","29.158 pontos", "11.946 pontos", "5.975 pontos" ]
Enter fullscreen mode Exit fullscreen mode

Ao utilizar o map passando uma função anônima (identificada pela arrow function (() => {})) esperamos que o console nos retorne uma lista dos textos de todos aqueles elementos que obtivemos anteriormente.
Porém, para fazer a conversão de pontos para reais, temos que separar os elementos que identificam o valor de pontos e a palavra "pontos".

4. Separando o número do texto

Para essa etapa existem algumas formas que a classe String do js nos permite utilizar, como a função split ou replace. Vamos utilizar o método split nesse caso pois a estrutura de texto é simples. Possíveis valores que podemos encontrar nos textos são "1.234.567 pontos", "1.337 pontos" ou "500 pontos", então perceba que dividir a string no caractere de espaço já resolve nosso problema.

$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0]
    return priceStr
})
Enter fullscreen mode Exit fullscreen mode

E como esse método retorna um array de strings, na nossa estrutura queremos somente o primeiro elemento, pois o segundo será sempre a string "pontos".

Perceba que o caractere utilizado para dividir a string é consumido nessa operação, no nosso caso o espaço não está em nenhum dos 2 elementos.

Temos agora um desafio simples, que o número ainda está como string e ele possui separadores de centenas, e na conversão é considerado como um identificador de decimal, então para isso vamos retirar esses pontos com o método replaceAll da classe String.

$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    return priceStr
})
Enter fullscreen mode Exit fullscreen mode
// Output
[ "74377", "29158", "11946", "5975"]
Enter fullscreen mode Exit fullscreen mode

5. Convertendo de pontos para reais

Agora que temos o valor numérico de pontos, vamos transformá-lo em número para js e assim calcular o novo valor em reais. Para isso basta usar o método estático da classe Number parseInt que espera uma string e retorna o valor número inteiro. Caso quiséssemos converter um valor com decimal, utilizaríamos o método parseFloat .

$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    const price = Number.parseInt(priceStr)
    return price
})
Enter fullscreen mode Exit fullscreen mode
// Output
[ 74377, 29158, 11946, 5975]
Enter fullscreen mode Exit fullscreen mode

E agora basta multiplicar esse valor pelo quanto 1 ponto equivale a real. Vamos considerar que você aproveitou um bom pacote de 1000 pontos por 20 reais, então 1 ponto equivale a R$ 0.02. E agora aplicando esse fator em nossa função

$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    const price = Number.parseInt(priceStr)
    const PONTOS_2_REAIS = 0.02
    const newPrice = price * PONTOS_2_REAIS
    return newPrice
})
Enter fullscreen mode Exit fullscreen mode
// Output
[ 1487.54, 583.16, 238.92000000000002, 119.5]
Enter fullscreen mode Exit fullscreen mode

É uma boa prática definir números mágicos como constantes e outros valores fixos com variáveis escritas em capslock

Em teoria já temos os novos valores, porém estamos tendo alguns problemas de conversão de binário para sua representação em Ponto Flutuante e não estamos apresentando com a cifra (R$) corretamente.

6. Apresentação do valor

Para apresentar um valor numérico basta utilizarmos o método da classe Number toFixed que fixa o valor em quantas casas decimais você quiser, no nosso caso, queremos somente 2 casas decimais.

$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    const price = Number.parseInt(priceStr)
    const PONTOS_2_REAIS = 0.02
    const newPrice = price * PONTOS_2_REAIS
    const priceFixed = (newPrice).toFixed(2)
    return priceFixed
})
Enter fullscreen mode Exit fullscreen mode
// Output
[ "1487.54", "583.16", "238.92", "119.50"]
Enter fullscreen mode Exit fullscreen mode

Porém, melhor ainda do que somente apresentar o número com as casas decimais, seria ótimo apresentar já com a cifra e os separados de centenas e decimais. E pra isso temos uma classe de internacionalização disponível no JS, chamada Intl. Com ela podemos lidar com plural, apresentação de datas e moedas.
Então basta passar o valor do novo preço em reais dos produtos para o método NumberFormat com os parâmetros de localização desejados e o estilo e moeda que iremos utilizar.

$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    const price = Number.parseInt(priceStr)
    const PONTOS_2_REAIS = 0.02
    const newPrice = price * PONTOS_2_REAIS
    const newStr = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(newPrice)
    return newStr
})
Enter fullscreen mode Exit fullscreen mode
// Output
[ "R$ 1.487,54", "R$ 583,16", "R$ 238,92", "R$ 119,50"]
Enter fullscreen mode Exit fullscreen mode

E agora, para terminar, basta substituirmos o valor original do elemento na página, para ficar mais claro quanto aquele produto realmente está custando.

7. Substituir valor original

Não tem mistério algum para trocar o valor original, inclusive vamos utilizar os conhecimentos anteriores para isso, simplesmente atribuindo o novo valor ao innerText do elemento.
Mas como não queremos mais retornar nada no console, vamos trocar o método inicial do array de map para forEach, e vamos retirar o retorno e vamos colocar a atribuição

$$('span.price').forEach((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    const price = Number.parseInt(priceStr)
    const PONTOS_2_REAIS = 0.02
    const newPrice = price * PONTOS_2_REAIS
    const newStr = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(newPrice)
    el.innerText = newStr
})
Enter fullscreen mode Exit fullscreen mode

E após rodar esse script em seu console estará pronta a nossa conversão de pontos de milhas para Reais, onde todos os elementos de pontos foram transformados em valores para reais.
Novo valor em reais
Perceba como a estilização se manteve a mesma, pois o elemento é o mesmo, o que mudamos foi o contéudo de texto.

Conclusão

Depois de pequenas operações e utilizando ótimos métodos do próprio Javascript pudemos ter noção do quanto realmente vale alguns produtos.
Espero ter ajudado de alguma forma a ampliar o seu conhecimento em js ou em programação no geral. Qualquer dúvida ou se tive alguma sugestão de como melhorar, estou disponível em minhas redes. vlw 🤙🤙.

Top comments (1)

Collapse
 
emersonlaranja profile image
Laranja

Muito interessante! Desconhecia esse operador $$ e foi muito bom ver às operações simples do JavaScript resolvendo problemas reais.