masked method work incorrectly with unmasked results
Describe the bug
All inputs have activated number mask with local pt-BR. Last input calculate sum for all other inputs and have mask too:
const mask = new Mask({ number: { locale: 'pt-BR', fraction: 2 } })
const totalAmount = Array.rom(document.querySelectorAll('.inputs')).reduce((agg, target) => {
const value = target.value ? parseFloat(mask.unmasked(target.value.toString())) : 0
return agg + (isNaN(value) ? 0 : value)
}, 0)
document.querySelector('.totalInput').value = totalAmount.toString()
document.querySelector('.totalInput').dispatchEvent(new Event('input', { bubbles: true })) // trigger mask.js
This lead that number incorrectly masked in total field. Instead of 10.34 it get 1034. So this mean:
mask.masked(mask.unmasked('10.234,54')) !== '10.234,54'
Steps to reproduce
const { Mask } = Maska;
const mask = new Mask({ number: { locale: 'pt-BR', fraction: 2 } })
console.log('correct', mask.unmasked('10.234,54')) // correct 10234.54
console.log('incorrect', mask.masked('10234.54')) // incorrect 1.023.454 (should be "10.234,54")
console.log('incorrect', mask.masked(mask.unmasked('10.234,54')), '!==', '10.234,54')
Reproduction link
https://github.com/beholdr/maska/issues/225 - If I understand correctly, in both cases, the masked handles the float attribute value as an integer: what is incorrectly or not expected.
question here: should mask.masked(mask.unmasked(a)) === a or we should expect non deterministic results?
@rozsazoltan - it is number (float), not integers. and it lost fraction
I think problem, that for mask.masked it should not expect value in opts.locale, but in locale, which it did mask.unmasked, which looks like en
Yes, it's a known issue with some locales. You can pass initially formatted value as a workaround:
mask.masked(Intl.NumberFormat({ locale: 'pt-BR' }).format(10234.54)) // = 10.234,54
Yes, but why mask.masked(mask.unmasked(a)) === a non deterministic? If you return unmasked in locale, which you not expect to handle in masked, this mean logic is incorrect.
const mask = new Mask({ number: { locale: 'pt-BR', fraction: 2 } })
Intl.NumberFormat('pt-BR').format(10234.54) // 10.234,54
mask.masked('10.234,54') // 10.234,54 - same, just waste cpu time
as I understand, expectation:
const number = 10223.34
const numberAsStr = number.toString() // '10223.34'
mask.masked('10223.34') // should return '10.223,34', but not working
mask.unmasked('10.223,34') // should return '10223.34', so parseFloat('10223.34') => 10223.34
and this is not happening now
Yeah, it’s currently not working with locales that have dot as separator. 10223.34 is not the same as 10.234,54 that’s why I suggest to pass value pre-formatted with Intl.NumberFormat.format()
If you have a universal solution for parsing all locales, PR are welcome.
@beholdr I think stuff like "parsing" and "formating" need to be split, so parsing can work with normal numbers (not only based on locale), while "formating" do format based requested locale
@le0pard I agree with that, but it’s more complicated. Problem is not to parse a correctly formatted number like 10.234,56. Problem is to parse a partially formatted number, like you have 10.234,56 and then press a backspace and get 10.234,5 which you should parse to correct float. I just couldn't solve this case at the time.
Hey @beholdr I saw you ran a quick root cause analysis. Would you be open to a contribution with a possible fix?
@arthurgousset yes, of course. Unfortunately, I don't have time for deep analysis right now. But if you can solve this issue, it will be cool.
@beholdr Unfortunately it looks like this is a larger design question. Our tool (workback.ai) works best with self contained, well defined bugs. Are there any such bugs you'd welcome a contribution for?
works best with self contained, well defined bugs
in this case for now it useless, because such task can do even beginner developer :)
such task can do even beginner developer
That's a great point @le0pard, would you say all self-contained bugs are successfully resolved by junior developers in repos you work in?
yes
That's awesome, sounds like you are on top of your game in the repos you work in!