Fetching Data using Headers

Making an API call without headers can be done right in the code fence of an Astro file:

//src/pages/experiments/data-fetching.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';

const allPokemonResponse = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=15`);
const allPokemonResult = await allPokemonResponse.json();
const allPokemon = allPokemonResult.results;
---
<BaseLayout title="Data Fetching" >
    <h1>Fetching data from an API call</h1>
    <h3>Fetch is in the frontmatter</h3>
    {allPokemon.map((pokemon) => (<p>{pokemon.name}</p>))}
</BaseLayout>

But, if you need to use headers, for example to include an API token, then the data will have to be fetched in a component, and the component rendered in your .astro file.

//src/pages/experiments/fetching-data-api-headers.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';

import BirdFetchComponent from '../../components/BirdFetchComponent.jsx';
---
<BaseLayout title="Data Fetching" >
    <h1>Fetching data from an API call with token in header</h1>
    <h3>Fetch is performed in the component</h3>
   <BirdFetchComponent client:load />
</BaseLayout>

(code for the component is below the component being rendered)


Get a list of recently-observed birds in your area!

Current location set:

Reported in the last 14 days...



//src/components/BirdFetchComponent.jsx
import React from "react";
import { useState } from "react";

export default function BirdFetchComponent() {
  const [recentBirds, setRecentBirds] = useState([]);
  const [location, setLocation] = useState("");

  async function getBirdSightings(event) {
    event.preventDefault();
    setLocation(event.target.elements.location.value.toUpperCase());
    const queryLocation = event.target.elements.location.value.toUpperCase();
    const recentUrl = `https://api.ebird.org/v2/data/obs/${queryLocation}/recent?back=14`;
    const myHeaders = new Headers();
    myHeaders.append("X-eBirdApiToken", "+0k3Ns+rInG");

    const requestOptions = {
      method: "GET",
      headers: myHeaders,
      redirect: "follow"
    };
    const response = await fetch(recentUrl, requestOptions);
    const data = await response.json();
    setRecentBirds(data);
  }

  return (
    <>
      <h3>Get a list of recently-observed birds in your area!</h3>
      <h5 className="birdtab">Current location set: {location} </h5>

      <form onSubmit={getBirdSightings}>
        <input
          name="location"
          type="text"
          placeholder="eBird region ID eg. CA-PE"
          style={{ textTransform: "uppercase" }}
        />
        <button> See the birds!</button>
      </form>

      <h3>Reported in the last 14 days...</h3>
      {recentBirds.map((bird) => (
        <p> 
        {bird.howMany} {bird.comName}(s) seen at {bird.obsDt.toString().slice(11)} on {bird.obsDt.toString().slice(5,10)}
        </p>
      ))}
    </>
  );
}