Back to List

Fetching Experiment Data with the fetch API

Fetch gene and experiment data from servers using the fetch API. Learn Ajax async communication and JSON data handling through bio examples.

Beginner
|
75min
|
Verified (2026-06)
Ajaxfetch APIAsynchronous CommunicationJSONSPAServer Communication
Progress0/19 (0%)

Fetching Experiment Data with the fetch API

So far you've calculated experiment data with JavaScript and read/written files in a server environment with Node.js. But all that data was either hardcoded in your code or read from local files. In real research, data lives on servers across the network โ€” you search gene info on NCBI, pull sample lists from your lab's LIMS, and retrieve protein structures from public APIs.

This process is called Ajax. Think of it like sending samples to an external sequencing service โ€” you don't just sit in the lab waiting until results arrive. You continue other experiments and check the results when they come back. It works the same way on the web. You send a data request to the server, the browser keeps running without freezing, and updates the screen when the response arrives.

fetch: Requesting Data from a Server

fetch() is a function that asks the server "please give me this data." Like typing a gene name into NCBI and hitting the search button.

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    return response.text();
  })
  .then(function(data) {
    console.log(data);
  });

console.log("Request sent, continuing other work");

This code operates in three steps:

  1. fetch(url) โ€” sends a request to the server
  2. .then(function(response) { ... }) โ€” schedules work to run when the response arrives
  3. .then(function(data) { ... }) โ€” receives and processes the data

The key word is schedules. fetch doesn't wait for the response โ€” it immediately moves to the next line. That's why "Request sent, continuing other work" prints first, and the code inside .then only runs after the server response arrives.

Asynchronous: The A in Ajax

The most important letter in Ajax is the first one โ€” A for Asynchronous.

Let's use a gene analysis request as an analogy:

javascript
// If it were synchronous:
// 1. Send samples to sequencing company
// 2. Wait 5 days in the lab doing nothing
// 3. Results arrive, only then start next experiment
// โ†’ Lab utilization: terrible

// Asynchronous โ€” how it's actually done:
// 1. Send samples to sequencing company
// 2. While waiting: culture cells, prepare buffers, read papers
// 3. Results notification arrives โ†’ check then and proceed
// โ†’ Lab utilization: optimal

Let's verify with code:

javascript
function showGeneInfo() {
  console.log("Gene info received");
}

fetch("https://api.example.com/gene/BRCA1").then(showGeneInfo);

console.log(1);
console.log(2);

Output:

text
1
2
Gene info received

1, 2 print first. That's because fetch only sends the request and immediately moves to the next line. showGeneInfo only runs later when the server response arrives. While the browser downloads data, scrolling, clicking, and typing all work normally. That's the power of asynchronous.

Shortening Code with Anonymous Functions

The named function showGeneInfo above is only used once inside .then. In cases like this, you can insert it directly without a name:

javascript
// Named function
function showResult() {
  console.log("Result arrived");
}
fetch("https://api.example.com/gene/TP53").then(showResult);

// Anonymous function โ€” same behavior
fetch("https://api.example.com/gene/TP53").then(function() {
  console.log("Result arrived");
});

The server's response is automatically passed to the function inside .then. You can name the parameter whatever you want โ€” by convention, it's called response:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    console.log(response);
  });

Think of a lab report arriving in an envelope. response is that envelope โ€” it contains not just the actual data but meta-information like "was the delivery successful?"

The Response Object: Opening the Envelope

The response contains detailed information about the communication result:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    console.log(response.status); // 200 (success)
    console.log(response.ok);     // true
  });

Key properties:

  • status โ€” HTTP status code. 200 means success, 404 means not found
  • ok โ€” true if the status code is in the 200โ€“299 range

Like a QC check, you can verify the response status before processing:

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    if (response.status === 404) {
      console.log("Gene not found");
    } else if (response.status === 200) {
      console.log("Data received successfully");
    }
  });

console.assert(200 >= 200 && 200 <= 299, "200 is in success range");
console.assert(404 < 200 || 404 > 299, "404 is outside success range");

JSON: The Standard Format for Experiment Data

Data from servers is usually in JSON (JavaScript Object Notation) format. Just as labs record all sample info in a standardized form, JSON is that standard form on the web.

javascript
// Gene data in JSON format
const geneDataJson = '{"name": "TP53", "chromosome": "17p13.1", "function": "tumor suppressor", "length_bp": 19149}';

// Convert JSON string โ†’ JavaScript object
const gene = JSON.parse(geneDataJson);

console.log(gene.name);        // "TP53"
console.log(gene.chromosome);  // "17p13.1"
console.log(gene.length_bp);   // 19149

console.assert(gene.name === "TP53", "Gene name verified");
console.assert(typeof gene.length_bp === "number", "Length is number type");

When receiving JSON data with fetch, use response.json():

javascript
fetch("https://api.example.com/gene/TP53")
  .then(function(response) {
    return response.json();
  })
  .then(function(gene) {
    console.log(gene.name);       // "TP53"
    console.log(gene.chromosome); // "17p13.1"
  });

response.text() returns the response as a plain string, while response.json() parses JSON and returns a JavaScript object. For structured data like experiment results, you'll almost always use .json().

Receiving multiple sample data as an array is also common:

javascript
const samplesJson = '[{"id": "S001", "od": 0.85, "pass": true}, {"id": "S002", "od": 0.12, "pass": false}, {"id": "S003", "od": 1.23, "pass": true}]';

const samples = JSON.parse(samplesJson);

for (let i = 0; i < samples.length; i++) {
  const status = samples[i].pass ? "PASS" : "FAIL";
  console.log(`${samples[i].id}: OD=${samples[i].od} โ†’ ${status}`);
}
// S001: OD=0.85 โ†’ PASS
// S002: OD=0.12 โ†’ FAIL
// S003: OD=1.23 โ†’ PASS

console.assert(samples.length === 3, "3 samples");
console.assert(samples[1].pass === false, "S002 is FAIL");

SPA: Apps That Don't Reload the Entire Page

Using the fetch we learned, you can build SPAs (Single Page Applications). These work by swapping only the needed parts within a single HTML page.

Think of a LIMS (Laboratory Information Management System). Click "DNA Extraction" in the left menu and the corresponding protocol appears in the right panel. Click "PCR" and the PCR protocol appears in the same spot. The entire page doesn't reload โ€” only the content area changes.

javascript
function loadProtocol(name) {
  fetch("https://api.example.com/protocols/" + name)
    .then(function(response) {
      return response.text();
    })
    .then(function(content) {
      document.querySelector("#protocol-content").innerHTML = content;
    });
}

// Load protocol on button click
// loadProtocol("dna-extraction");
// loadProtocol("pcr");

document.querySelector("#protocol-content") pinpoints a specific area, and innerHTML replaces only its contents. Everything else (header, menu, footer) stays intact. This is the essence of SPA.

One important note โ€” when using innerHTML, you must select only the exact area you want to change. If you select a parent element, all its child elements will be wiped out too. It's like trying to cut and paste a specific lane from a gel image and accidentally erasing the adjacent lanes.

Separating Data and Logic

Good code separates data from logic. If you mix experiment protocols (procedures) and sample lists (data) in the same document, you have to touch the protocol document every time samples change. That risks accidentally breaking the procedure.

Code works the same way. Ideally, data like gene lists lives in a separate file (or server), and your code uses fetch to retrieve and process it:

javascript
// Data: stored in a JSON file on the server
// [{"name": "TP53", "type": "tumor suppressor"},
//  {"name": "BRCA1", "type": "DNA repair"},
//  {"name": "EGFR", "type": "receptor tyrosine kinase"}]

// Logic: JavaScript fetches data and displays on screen
fetch("https://api.example.com/genes")
  .then(function(response) {
    return response.json();
  })
  .then(function(genes) {
    let listHtml = "";
    for (let i = 0; i < genes.length; i++) {
      listHtml += "<li>" + genes[i].name + " โ€” " + genes[i].type + "</li>";
    }
    document.querySelector("#gene-list").innerHTML = listHtml;
  });

Even if genes grow to 100, not a single line of JavaScript needs to change. Just update the JSON data on the server.

Try It Yourself (Faded Example)

Fill in the blanks to complete code that fetches gene info from a server and displays it on screen.

Fill in the Blanksjavascript
fetch("https://api.example.com/gene/TP53")
.then(function() {
return response.json();
})
.then(function(gene) {
const info = gene.name + " (" + gene. + ")";
document.querySelector("#result").innerHTML = ;
});

Common Errors & Solutions

Q: How do I use variables created inside .then outside it?

response or gene only exist inside the .then function. Accessing them outside gives undefined. All code that uses the data must go inside .then. Async results must be processed "when they arrive."

Q: response.json() throws an error

This happens when the server response isn't valid JSON. First use response.text() and console.log to check the actual content. It might be an HTML error page or an empty response.

Q: fetch request doesn't work (CORS error)

If you see a "CORS" error in the browser console, the server isn't allowing external access. Either run a local dev server (npx serve) to fetch files from the same server, or use a public API that allows CORS.

Q: What's the difference between =, ===, and ==?

= is assignment (sets a value), === is strict comparison (checks both type and value), == is loose comparison (converts types before comparing). In conditionals like if (response.status === 200), always use ===.

๐Ÿ’ฌ Questions & Comments

0 comments

You can post without signing in. Guest comments cannot be edited or deleted by their author.

0/2000

Loading...