JavaScript è un linguaggio che dispone di pochi tipi di dati. Questa caratteristica può risultare problematica quando si ha a che fare con un database come MongoDB.
Gli operatori di confronto sui dati di MongoDB sono concepiti per effettuare una verifica sul tipo di dati passato alla query. Se il tipo di dati non corrisponde con quello del campo scelto, il confronto non avrà luogo.
Consideriamo questa query:
db.products.find({price: {$gte: 100}});
Questa query funzionerà nel modo sperato solo se il campo price
contiene valori interi. Se al contrario dovesse contenere anche valori in virgola mobile, l'operatore verrebbe
semplicemente ignorato.
Se stiamo implementando un sistema di ricerca basato sul prezzo, potremmo scrivere il seguente codice:
app.get('/search', (req, res) => {
let price = req.query.price;
// TODO: validazione
if(price.length > 0) {
db.products.find({price: {$gte: price}}).then(results => {
res.json(results);
}).catch(err => {
res.json(err);
});
} else {
res.json({});
}
});
Cosa succede quando riceviamo dal form di ricerca un valore intero? Potremmo provare a convertirlo in un valore in virgola mobile:
let value = '100';
let v = parseFloat(value); // '100'
let k = parseFloat(Number(value).toFixed(2)); '100'
Questo accade perché JavaScript non ha un tipo di dati per i valori in virgola mobile e per gli interi come MongoDB: entrambi sono istanze di Number
.
Dobbiamo quindi ricorrere ad una diversa soluzione:
const convertIntToDouble = (value) => {
if( /^\d+$/.test( value ) ) {
let n = parseInt(value, 10);
return (n + 0.01);
} else {
return -1;
}
}
In pratica aggiungiamo manualmente una parte decimale trascurabile al numero intero in modo da avere come risultato un numero in virgola mobile.