Skip to content

Commit

Permalink
Get the Stop Pane to work on a server side rendered page
Browse files Browse the repository at this point in the history
* Extract the logic of the REST API proxy endpoints into JS functions
* Server-side render the contents of the stop details page (i.e. click a stop on the map and then refresh the web page)
* Only load data from the server in StopPane when it's missing needed data.
  • Loading branch information
aaronbrethorst committed Jul 19, 2024
1 parent 1dfdc5a commit 919568e
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 67 deletions.
38 changes: 26 additions & 12 deletions src/components/oba/StopPane.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,45 @@
import ArrivalDeparture from '../ArrivalDeparture.svelte';
export let stop;
export let arrivalsAndDeparturesResponse = null;
let arrivalsAndDepartures;
let loading = false;
let error;
let routeShortNames = null;
async function loadData(stopID) {
loading = true;
const response = await fetch(`/api/oba/arrivals-and-departures-for-stop/${stopID}`);
if (response.ok) {
const json = await response.json();
arrivalsAndDepartures = json.data.entry;
routeShortNames = json.data.references.routes
.filter((r) => stop.routeIds.includes(r.id))
.map((r) => r.nullSafeShortName)
.sort();
arrivalsAndDeparturesResponse = await response.json();
arrivalsAndDepartures = arrivalsAndDeparturesResponse.data.entry;
} else {
error = 'Unable to fetch arrival/departure data';
}
loading = false;
}
$: (async (s) => {
await loadData(s.id);
})(stop);
$: (async (s, arrDep) => {
// if the arrivalsAndDeparturesResponse is passed in, use that
// instead of loading fresh data.
if (arrDep) {
arrivalsAndDepartures = arrDep.data.entry;
}
else {
await loadData(s.id);
}
})(stop, arrivalsAndDeparturesResponse);
let _routeShortNames = null;
function routeShortNames() {
if (!_routeShortNames) {
_routeShortNames = arrivalsAndDeparturesResponse.data.references.routes
.filter((r) => stop.routeIds.includes(r.id))
.map((r) => r.nullSafeShortName)
.sort();
}
return _routeShortNames;
}
</script>

<div>
Expand Down Expand Up @@ -64,8 +78,8 @@
<div class="h-36 rounded-lg bg-[#1C1C1E] bg-opacity-80 p-4">
<h1 class="text-xl font-semibold text-white">{stop.name}</h1>
<h1 class="text-lg text-white">Stop #{stop.id}</h1>
{#if routeShortNames}
<h1 class="text-lg text-white">Routes: {routeShortNames.join(', ')}</h1>
{#if routeShortNames()}
<h1 class="text-lg text-white">Routes: {routeShortNames().join(', ')}</h1>
{/if}
</div>
</div>
Expand Down
17 changes: 17 additions & 0 deletions src/lib/RestAPI/arrivalsAndDeparturesForStop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { error, json } from '@sveltejs/kit';

import { PUBLIC_OBA_SERVER_URL as baseURL } from '$env/static/public';
import { PRIVATE_OBA_API_KEY as apiKey } from '$env/static/private';

export default async function(stopID) {
const apiURL = `${baseURL}/api/where/arrivals-and-departures-for-stop/${stopID}.json?key=${apiKey}`;
const response = await fetch(apiURL);

if (!response.ok) {
error(500, 'Unable to fetch arrivals-and-departures-for-stop.');
return;
}

const data = await response.json();
return json(data);
}
16 changes: 16 additions & 0 deletions src/lib/RestAPI/stop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { error, json } from '@sveltejs/kit';

import { PUBLIC_OBA_SERVER_URL as baseURL } from '$env/static/public';
import { PRIVATE_OBA_API_KEY as apiKey } from '$env/static/private';

export default async function(stopID) {
const apiURL = `${baseURL}/api/where/stop/${stopID}.json?key=${apiKey}`;
const response = await fetch(apiURL);

if (!response.ok) {
return error(500, 'Unable to fetch arrivals-and-departures-for-stop.');
}

const data = await response.json();
return json(data);
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
import { error, json } from '@sveltejs/kit';

import { PUBLIC_OBA_SERVER_URL as baseURL } from '$env/static/public';

import { PRIVATE_OBA_API_KEY as apiKey } from '$env/static/private';
import arrivalDepartureAPI from '$lib/RestAPI/arrivalsAndDeparturesForStop';

/** @type {import('./$types').RequestHandler} */
export async function GET({ params }) {
const stopID = params.id;
const apiURL = `${baseURL}/api/where/arrivals-and-departures-for-stop/${stopID}.json?key=${apiKey}`;
const response = await fetch(apiURL);

if (!response.ok) {
error(500, 'Unable to fetch arrivals-and-departures-for-stop.');
return;
}

const data = await response.json();
return json(data);
return arrivalDepartureAPI(params.id);
}
16 changes: 2 additions & 14 deletions src/routes/api/oba/stop/[stopID]/+server.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
import { error, json } from '@sveltejs/kit';

import { PUBLIC_OBA_SERVER_URL as baseURL } from '$env/static/public';
import { PRIVATE_OBA_API_KEY as apiKey } from '$env/static/private';
import stopAPI from '$lib/RestAPI/stop';

/** @type {import('./$types').RequestHandler} */
export async function GET({ params }) {
const stopID = params.stopID;
const apiURL = `${baseURL}/api/where/stop/${stopID}.json?key=${apiKey}`;
const response = await fetch(apiURL);

if (!response.ok) {
return error(500, 'Unable to fetch arrivals-and-departures-for-stop.');
}

const data = await response.json();
return json(data);
return stopAPI(params.stopID);
}
16 changes: 16 additions & 0 deletions src/routes/stops/[stopID]/+page.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import stopAPI from '$lib/RestAPI/stop.js';
import arrivalDepartureAPI from '$lib/RestAPI/arrivalsAndDeparturesForStop.js';

export async function load({ params }) {
const stopID = params.stopID;
const stopResponse = await stopAPI(stopID);
const stopBody = await stopResponse.json();
const arrivalsAndDeparturesResponse = await arrivalDepartureAPI(stopID)
const arrivalsAndDeparturesResponseJSON = await arrivalsAndDeparturesResponse.json();

return {
stopID: params.stopID,
stopData: stopBody.data,
arrivalsAndDeparturesResponse: arrivalsAndDeparturesResponseJSON
}
}
32 changes: 7 additions & 25 deletions src/routes/stops/[stopID]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
<script context="module">
import StopPane from '../../../components/oba/StopPane.svelte';
export async function load({ params }) {
const stopID = params.stopID;
const response = await fetch(`/api/oba/stops/${stopID}`);
if (!response.ok) {
return {
status: response.status,
error: new Error('Failed to fetch stop data')
};
}
const stopData = await response.json();
return {
props: {
stopData
}
};
}
</script>

<script>
export let stopData;
import StopPane from '$components/oba/StopPane.svelte';
export let data;
const stop = data.stopData.entry;
const arrivalsAndDeparturesResponse = data.arrivalsAndDeparturesResponse;
</script>

<StopPane {stopData} />
<div class='pt-20 px-8 max-w-5xl mx-auto'>
<StopPane {stop} {arrivalsAndDeparturesResponse} />
</div>
1 change: 1 addition & 0 deletions svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const config = {
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
alias: {
$components: './src/components',
$images: './src/assets/images'
}
},
Expand Down

0 comments on commit 919568e

Please sign in to comment.