Speciaal voor 50-plussers: met AI bouw je je eigen producten en verkoop je ze. Geen code nodig.

Formulier verzendt geen data? Zo debug je de koppeling

Debugscherm met netwerktab en mislukte formulier POST request op laptop

Mijn formulier verzendt geen data. De knop gaf netjes een succesmelding, terwijl de tabel in de database leeg bleef. Na een middag logs lezen vond ik een ontbrekende CORS-header in de API. Sindsdien debug ik elke formulierkoppeling in drie lagen: browser, API en database.

Dat klinkt als veel werk, maar het scheelt eindeloos in code graven. Het vervelende aan een formulier dat niets opslaat is dat de fout vrijwel nooit op de plek zit waar je als eerste kijkt. De frontend kan groen licht geven terwijl de request nooit is verstuurd. De API kan een 200 teruggeven terwijl de insert mislukt. En de database kan een rij opslaan in een tabel waar jij niet naar kijkt.

Net als bij een AI-chatbot die slechte antwoorden geeft zit het probleem vaak in aannames. Je denkt dat de klik een request verstuurt, maar ergens stopt de keten.

Formulier verzendt geen data? Kijk eerst in de browser

Open de netwerktab van je browser, filter op fetch of XHR, en verstuur het formulier opnieuw. Zie je helemaal geen request? Dan stopt de fout in je frontend. Dat gebeurt vaker dan je denkt.

De klassieker is een submit-handler die preventDefault aanroept en daarna crasht. De gebruiker ziet een spinner of een succesmelding, maar er gaat nooit iets naar de server. Een andere stille bug is een button zonder type submit. Als je alleen op een click-event luistert, kan een enter-toets het formulier afgaan zonder jouw code te raken.

Staat er wel een request? Check dan de payload. Een leeg request body wijst bijna altijd op inputs zonder name-attribuut. FormData neemt alleen velden met een name mee. Een vergeten name is genoeg om een lege body te sturen, terwijl alles op het scherm klopt. Controleer ook of je geen disabled inputs of onzichtbare velden verwacht te versturen.

Volg de request naar je backend

De volgende stop is je API. Kijk eerst naar de statuscode. Bij een 400 of 422 heeft je server de request geweigerd. Lees de response body, want daar staat meestal welke validatie faalt. Vaak is het een enkel veld dat een getal verwacht maar een string krijgt, of andersom. Bij een 500 heb je een stacktrace nodig en zit de fout in je serverlogica.

Zie je in de browser een netwerkfout maar in de logs van je server helemaal geen request? Denk aan CORS. De browser stuurt eerst een preflight OPTIONS request. Als je API daar niet goed op antwoordt, blokkeert de browser de echte POST. De fout lijkt dan in je frontend te zitten, maar je server heeft nooit iets gezien.

Let ook op de content-type. Ik had laatst een formulier dat netjes JSON stuurde met application/json, terwijl de PHP-code $_POST las. Die blijft leeg bij JSON in de body. Een file_get_contents(‘php://input’) en json_decode maakten het werkend. Het is zo’n fout die je over het hoofd ziet omdat de code er logisch uitziet.

Dit is ook het moment om niet blind opnieuw code te genereren. De request zelf vertelt je welke kant het op moet. Net als bij een AI-code bug die blijft terugkomen helpt het om de logica uit te lezen in plaats van de code opnieuw te schrijven.

Test je endpoint apart

Gebruik een losse tool zoals Postman of een curl-opdracht om dezelfde request te sturen. Werkt het daar wel? Dan ligt het aan de manier waarop je formulier de data verstuurt. Werkt het daar ook niet? Dan zit het in je backend-logica. Die split bespaart je een hoop heen en weer klikken in de browser.

Kijk pas daarna naar de database

Als je API een 200 teruggeeft en de data nog steeds ontbreekt, is de database aan de beurt. Het irritantste voorbeeld is een transactie die nooit is gecommit. Je ORM kan een sessie openen, een insert voorbereiden en teruggaan zonder commit. In je code lijkt alles gelukt, maar de database heeft de wijziging teruggedraaid.

Controleer ook of je naar dezelfde database kijkt als je code gebruikt. Met staging, migraties en Docker-compose draai ik nog steeds weleens per ongeluk tegen een lokale container terwijl ik in de productie-UI kijk. Eén verkeerde environment variable en je zoekt je suf.

Soms is de rij er wel, maar vindt je query hem niet. Denk aan soft deletes, een vergeten statusfilter of een tenant_id die niet overeenkomt. Draai een simpele select op de tabel en kijk of het veld er echt staat. Check daarna of je API iets anders teruggeeft dan wat er is opgeslagen.

Let ook op stille typeconversies. Een datumveld dat leeg blijft omdat je stringformaat niet klopt, of een boolean die als tekst ‘false’ wordt opgeslagen en in je query als 0 telt. De database kan data schrijven zonder dat jij het als fout ziet.

Veelgestelde vragen

Mijn formulier toont een succesmelding, maar er staat niets in de database. Waar kijk ik als eerste?

Begin in de netwerktab van je browser. Geen request betekent frontendprobleem. Wel een request betekent dat je statuscode en response body moet lezen. Daarna volg je de request via de serverlog naar de database.

Welke statuscode wijst op een probleem in het formulier zelf?

Een 4xx code zoals 400, 413 of 422 betekent dat je server de input weigert. Lees de response body. Een 200 betekent niet automatisch dat data is opgeslagen. Check dus altijd of er een rij is aangemaakt.

Mijn API geeft een CORS fout. Wat moet ik doen?

Controleer de preflight OPTIONS response. Je server moet de juiste Access-Control-Allow-Origin en Allow-Headers terugsturen. In productie is dit een veelvoorkomende oorzaak van netwerkfouten die er in de browser uitzien als een frontendbug.

Hoe test je snel of de database de data wel heeft ontvangen?

Gebruik een losse query of een tool die direct op de database kijkt. Zoek naar de laatst toegevoegde rij. Als die er is maar je API geeft hem niet terug, zit de fout in je read-query. Als de rij ontbreekt, zit de fout in je insert.

Debuggen is vooral volhouden: elke laag uitsluiten, net zolang tot er één laag met een duidelijke fout overblijft. Soms is het een vergeten name, soms een ontbrekende header, soms een commit die nooit wordt aangeroepen. De volgorde browser, API, database is het enige dat mij consequent bij de oplossing brengt.