Leçon 13 / 15

Assembler les données et les calculs

20 min Node.js — premiers scripts et serveur HTTP Gratuit

Objectif : Charger les commandes depuis le fichier JSON et calculer le total de chacune.

À ce stade, votre serveur sait lire les commandes et répondre à une requête, mais les données et leur total restent séparés. Vous allez les assembler pour obtenir, en mémoire, un total calculé pour chaque commande et contrôler le résultat dans le terminal.

Vous avez déjà créé `calculerTotal` et lu le fichier JSON dans les leçons précédentes. Ici, vous réutilisez ces éléments : la lecture fournit les commandes, puis une transformation associe à chacune le total de ses montants. La route HTTP existante reste en place ; cette étape ne change pas encore les données qu’elle renvoie.

Vérifier la forme des données

Le calcul utilisé dans cette leçon reçoit un tableau de montants. Chaque objet de commande doit donc contenir une propriété `montants` de ce type, en plus de sa référence et de son statut. Gardez les valeurs de votre fichier existant ; l’exemple ci-dessous montre seulement la structure attendue si vous devez la contrôler.

JSON
[
  {
    "reference": "BR-1001",
    "statut": "En préparation",
    "montants": [12.5, 8]
  },
  {
    "reference": "BR-1002",
    "statut": "À expédier",
    "montants": [18, 6.5]
  }
]

Dans cet exemple, le total de `BR-1001` est 20,50 et celui de `BR-1002` est 24,50. Les montants sont des nombres JSON, et non des chaînes entre guillemets : ils peuvent ainsi être additionnés directement par la fonction de calcul.

Assembler lecture et calcul

Mettez à jour `src/serveur.js` pour lire le fichier depuis la racine du projet, convertir son contenu, puis calculer un total pour chaque commande. `map` construit un nouveau tableau : chaque commande garde ses propriétés et reçoit en plus une propriété `total`. L’arrondi à deux décimales évite d’afficher des imprécisions liées aux nombres décimaux en JavaScript.

JavaScript
import { readFile, writeFile } from 'node:fs/promises';
import { createServer } from 'node:http';
import { calculerTotal } from './calculer-total.js';

const cheminCommandes = new URL('../data/commandes.json', import.meta.url);

async function chargerCommandes() {
  const contenu = await readFile(cheminCommandes, 'utf8');
  return JSON.parse(contenu);
}

async function afficherTotaux() {
  const commandes = await chargerCommandes();
  const commandesAvecTotaux = commandes.map((commande) => ({
    ...commande,
    total: Math.round(calculerTotal(commande.montants) * 100) / 100
  }));

  for (const commande of commandesAvecTotaux) {
    console.log(`${commande.reference} : ${commande.total.toFixed(2)} €`);
  }
}

const serveur = createServer(async (requete, reponse) => {
  if (requete.method === 'GET' && requete.url === '/commandes') {
    try {
      const commandes = await chargerCommandes();
      reponse.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
      reponse.end(JSON.stringify(commandes));
    } catch (erreur) {
      console.error('Erreur lors de la lecture des commandes :', erreur.message);
      reponse.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
      reponse.end(JSON.stringify({ erreur: 'Impossible de lire les commandes.' }));
    }
    return;
  }

  reponse.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
  reponse.end(JSON.stringify({ erreur: 'Route introuvable.' }));
});

try {
  await afficherTotaux();
} catch (erreur) {
  console.error('Erreur lors du calcul des totaux :', erreur.message);
}

serveur.listen(3000, () => {
  console.log('Serveur démarré sur le port 3000.');
});
Aperçu du rendu
Chargement de l'aperçu…
Résultat attendu
BR-1001 : 20.50 €
BR-1002 : 24.50 €
Serveur démarré sur le port 3000.

Le chemin construit avec `import.meta.url` est relatif à l’emplacement de `src/serveur.js` : le script trouve ainsi `data/commandes.json` même si vous le lancez depuis la racine du projet avec `node src/serveur.js`. L’import de `writeFile` est conservé pour les opérations d’écriture JSON déjà pratiquées ; cette étape ne réécrit pas le fichier, car le calcul ne doit pas modifier les données source.

Comprendre les deux traitements

`afficherTotaux` sert à vérifier les données au démarrage : elle charge le fichier, calcule les totaux et les affiche. Le gestionnaire HTTP conserve, lui, le comportement de la leçon précédente : `GET /commandes` renvoie les commandes telles qu’elles sont dans le fichier, et les autres requêtes reçoivent une réponse 404. La protection `try/catch` de la route consigne l’erreur côté serveur et renvoie une réponse 500 si la lecture échoue.

À retenir

  • Chargez les commandes puis convertissez le JSON avant de parcourir les données.
  • Appliquez `calculerTotal` aux montants de chaque commande et conservez le résultat en mémoire.
  • Vérifiez les références et les totaux affichés dans le terminal au lancement.
  • Gardez le traitement HTTP existant distinct de ce calcul de démonstration.

Dans la prochaine leçon, vous utiliserez les commandes chargées pour construire la réponse de la route HTTP destinée au suivi.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.