Quanto vale as suas milhas?
Tags: javascript, intl, devtools, portugues
Published: 2023-11-13 20:07:34

---
title: Quanto vale as suas milhas?
published: true
description: Artigo sobre APIs nativas recentes do Javascript aplicadas diretamente no DevTools para resolver um problema simples de melhor visualização do valor das suas milhas
tags: js, Intl, DevTools, portugues
# cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4kvg7p6hq149jot8nn0.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-11-13 17:54 +0000
---
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tv6hjd7e33wl8go9p9wy.png)

### 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](https://stackoverflow.com/questions/8981211/what-is-the-source-of-the-double-dollar-sign-selector-query-function-in-chrome-f). 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.

```js
$$('span.price')
```

```js
// Output
[span.price, span.price,span.price,span.price,span.price,span.price, ...]
```

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.

```js
$$('span.price').map((el) => {
    return el.innerText
})
```

```js
// Output
["74.377 pontos","29.158 pontos", "11.946 pontos", "5.975 pontos" ]
```

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`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) ou [`replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/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.

```js
$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0]
    return priceStr
})
```

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.

```js
$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    return priceStr
})
```

```js
// Output
[ "74377", "29158", "11946", "5975"]
```

### 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` .

```js
$$('span.price').map((el) => {
    const priceStr = el.innerText.split(' ')[0].replaceAll('.','')
    const price = Number.parseInt(priceStr)
    return price
})
```

```js
// Output
[ 74377, 29158, 11946, 5975]
```

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

```js
$$('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
})
```

```js
// Output
[ 1487.54, 583.16, 238.92000000000002, 119.5]
```

> É 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](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) 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.

```js
$$('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
})
```

```js
// Output
[ "1487.54", "583.16", "238.92", "119.50"]
```

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.

```js
$$('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
})
```

```js
// Output
[ "R$ 1.487,54", "R$ 583,16", "R$ 238,92", "R$ 119,50"]
```

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

```js
$$('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
})
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ionaol3h8dkxwt7ha8ic.png)
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 🤙🤙.