Fetch Notion database pages with API

by ludovicoiovino

HTML

<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
    <script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
    <script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
    <script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
    <script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
    <script type="text/javascript" charset="utf-8"
        src="https://js.api.here.com/v3/3.1/mapsjs-clustering.js"></script>

    <div class="page-header">
        <div id="alert-warning" style="display:none;">
  <span id="alert" onclick="this.parentElement.style.display='none';">&times;</span>
  <strong>Warning!</strong><br>Please paste your apiKey in the Javascript code.
</div>
       
    </div>
  <h5>
  <div id="loader" style="display: none; position: absolute; top: 10px; left: 10px; z-index: 1000;">
  🔄 Loading data...
</div>
  <span id="nrpoints"></span>
  </h5>
    <div id="map"></div>

    <script type="text/javascript" src='demo.js'></script>

CSS

#map {
    width: 100%;
    height: 800px;
    background: grey;
}

#panel {
    width: 100%;
    height: 800px;
}

#alert-warning {
border-style: none;
border-left-style: solid;
border-left-width: thick;
border-color: #f44336;
background-color: #f4c3c6;
padding-left: 4px;
border-radius: 15px;
padding: 20px;
color: black;
}
#alert {
margin-left: 15px;
color: black;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}
#alert:hover {
color: white;
}

JavaScript

async function getAllPages() {
  try {
    const response = await fetch('https://v0-cobol-backend.vercel.app/api/notion/pages');

    if (!response.ok) {
      const error = await response.text();
      throw new Error(`API error ${response.status}: ${error}`);
    }

    const json = await response.json();

    if (!json.success || !Array.isArray(json.pages)) {
      throw new Error('Unexpected API response structure');
    }

    return json.pages;
  } catch (error) {
    console.error('Failed to fetch pages:', error.message);
    return [];
  }
}

function extractDataPoints(pages) {
  const dataPoints = [];

  pages.forEach((page, index) => {
    const locText = page?.properties?.location?.rich_text?.[0]?.plain_text;
    if (!locText || !locText.includes(',')) return;

    const [latStr, lonStr] = locText.split(',');
    const lat = parseFloat(latStr);
    const lon = parseFloat(lonStr);
    if (isNaN(lat) || isNaN(lon)) return;

    const images = page?.properties?.Picture?.files;
    const firstImageUrl = images?.[0]?.external?.url || images?.[0]?.file?.url || null;

    const point = new H.clustering.DataPoint(lat, lon, undefined, { img: firstImageUrl }); // ✅ fixed
    dataPoints.push(point);
  });

  return dataPoints;
}


function moveMap(map){
//42.07098764905609, 13.358108593904555
  map.setCenter({lat:42.07098764905609, lng:13.358108593904555});
  map.setZoom(10);
}

/**
 * Boilerplate map initialization code starts below:
 */

//Step 1: initialize communication with the platform
// In your own code, replace variable apikey with your own apikey


/***********************
//
//********* please set apiKey here *************/
window.apiKey = 'KW2udl_0sQ4zKUqARSm0IBrTCGt_8wh2yfzkTFpiluY'; 
//
/***********************/


var alertWarningUi = document.getElementById('alert-warning');

if(!apiKey){
	alertWarningUi.style.display= 'block';
} else{
	alertWarningUi.style.display =...