Aller au contenu
← 1001 Widgets
N° 023 · ●●○

Convertisseur de devises

Euro, franc suisse, dollar canadien : un convertisseur au taux du jour publié par la Banque centrale européenne. Le bon exercice pour appeler une API et prévoir le cas où elle ne répond pas.

JSAPI
Ce qu'on apprend
  • Charger des taux avec fetch
  • Calculer un taux croisé à partir de l'euro
  • Prévoir un repli quand le réseau échoue
Pourquoi ce langage

Pourquoi un convertisseur de devises ? Entre la Belgique, la Suisse et le Canada, on jongle sans cesse entre euros, francs et dollars. Un convertisseur au taux du jour évite les approximations.

Les taux viennent de Frankfurter, une API gratuite et sans clé qui republie ceux de la Banque centrale européenne. Tous sont donnés par rapport à l'euro : pour convertir des francs en dollars, on passe par l'euro avec une simple division.

Pourquoi en JavaScript simple ? Un fetch, un objet de taux, une division. Et surtout, une solution de repli si l'API ne répond pas.

Comment ça marche
  1. LE HTML

    <input id="montant" inputmode="decimal" value="100">
    <select id="de"></select> <select id="vers"></select>
    <output id="resultat"></output>
  2. LES TAUX

    Frankfurter renvoie tous les taux par rapport à l'euro.

    let taux = { EUR: 1 };
    async function chargerTaux() {
      const r = await fetch('https://api.frankfurter.dev/v1/latest?from=EUR&to=CHF,CAD,USD,GBP');
      if (!r.ok) throw new Error('Taux indisponibles');
      const data = await r.json();
      taux = { EUR: 1, ...data.rates };
    }
  3. LE TAUX CROISÉ

    De CHF vers USD : on passe par l'euro.

    const tauxEntre = (a, b) => taux[b] / taux[a];
  4. LIRE UN MONTANT À LA FRANÇAISE

    « 1 250,50 » doit devenir 1250.5.

    const lire = t => Number(t.replace(/\s/g, '').replace(',', '.'));
  5. CONVERTIR

    function convertir() {
      const montant = lire(document.getElementById('montant').value);
      const a = document.getElementById('de').value, b = document.getElementById('vers').value;
      const fmt = new Intl.NumberFormat('fr-BE', { style: 'currency', currency: b });
      document.getElementById('resultat').textContent =
        isNaN(montant) ? 'Montant invalide' : fmt.format(montant * tauxEntre(a, b));
    }
    
    chargerTaux().catch(() => { taux = { EUR: 1, CHF: 0.94, CAD: 1.6, USD: 1.16, GBP: 0.86 }; }).finally(convertir);
Pièges

PIÈGE 1 : Oublier la virgule

Piège

Mauvais : Number('12,50'). Le résultat vaut NaN, alors qu'en Belgique c'est ainsi qu'on écrit.

Fix

Correct : retirer les espaces et remplacer la virgule par un point avant de convertir.

PIÈGE 2 : Une page blanche hors ligne

Piège

Mauvais : ne rien prévoir si fetch échoue. Le convertisseur reste vide sans explication.

Fix

Correct : un catch qui charge des taux indicatifs, et un message qui le dit clairement.

PIÈGE 3 : Recharger à chaque frappe

Piège

Mauvais : appeler l'API à chaque modification du montant. Des dizaines de requêtes pour des taux qui changent une fois par jour.

Fix

Correct : charger les taux une fois, puis calculer localement.

PERSONNALISER
  • Une liste de devises favorites en haut du menu.
  • L'historique sur 30 jours avec l'adresse /v1/2025-01-01..?from=EUR de la même API.
  • Un mode voyage : le montant saisi dans la devise locale s'affiche directement en euros.
OPTIMISATION
  • Gardez les taux en cache dans localStorage avec leur date, et ne rechargez que le lendemain.
  • Les taux de la BCE sont publiés vers 16 h : avant cette heure, ce sont ceux de la veille.
VERS REACT

Les taux se chargent dans un useEffect au premier rendu, avec un état de chargement et un état d'erreur.

Le montant et les deux devises vivent dans des useState, le résultat se calcule pendant le rendu.

Pour une vraie application, une bibliothèque comme TanStack Query gère le cache et les nouvelles tentatives.

Commentaires
0/1000

Chargement des commentaires…