Eventingo — wyszukiwarka wydarzeń przez Ticketmaster API
Projekt Node.js · Express · EJS · Ticketmaster API

Eventingo — znajdź co gra w Twoim mieście

Prosta aplikacja webowa, która odpowiada na jedno pytanie: co się dzieje w podanym mieście przez najbliższe 7 dni? Użytkownik wpisuje nazwę miasta, serwer odpytuje Ticketmaster Discovery API i zwraca listę wydarzeń — koncertów, festiwali, spektakli — z datą, miejscem i linkiem do zakupu biletów.

Node.js Express.js EJS Axios Ticketmaster API SSR

Projekt skupiony na jednej kompetencji: integracji z zewnętrznym REST API. Żadnej bazy danych, żadnych sesji, żadnej autentykacji — tylko formularz, żądanie HTTP do Ticketmaster i wyrenderowany wynik. Cały backend to 77 linii JavaScript.

Zakres dat jest obliczany automatycznie po stronie serwera — zawsze “teraz” do “teraz + 7 dni”, sformatowane do wymaganego przez API formatu ISO 8601 UTC (2024-11-15T00:00:00Z). Użytkownik nie musi podawać dat.

01Wygląd aplikacji

Ciemna, eventowa estetyka — pełnoekranowe hero z gradientowym tłem na zdjęciu, białe logo z grubą ramką i dużymi literami, formularz wyszukiwania wyśrodkowany na środku ekranu. Po wyszukaniu strona przewija się do siatki kart wydarzeń na głębokiej bordo-pomarańczowej palecie.

Search events nearby your city
Write your city location
Your city name
Submit
↓ wyniki dla “Warsaw” — 7 najbliższych dni
Rock Night Festival 2024
📅 2024-11-16
📍 Tauron Arena Kraków
See more →
Jazz in the City
📅 2024-11-18
📍 Stodoła Warsaw
See more →
Stand-up Comedy Special
📅 2024-11-20
📍 Palladium Warsaw
See more →

↑ rekonstrukcja interfejsu na podstawie kodu CSS i HTML

02Jak działa aplikacja

1

Użytkownik wpisuje miasto

Formularz HTML wysyła POST do /submit z polem location.

2

Serwer oblicza zakres dat

Node.js buduje dwa obiekty Date — teraz i teraz+7 dni — i formatuje je do ISO 8601 UTC wymaganego przez Ticketmaster (YYYY-MM-DDTHH:mm:00Z).

3

Axios odpytuje Ticketmaster Discovery API v2

Parametry: apikey, city, startDateTime, endDateTime. Odpowiedź zawiera zagnieżdżoną strukturę _embedded.events.

4

Mapowanie danych

Serwer wyciąga tylko potrzebne pola: event.name, event.dates.start.localDate, event._embedded.venues[0].name, event.url.

5

EJS renderuje wynik

Przetworzona tablica trafia do szablonu index.ejs jako zmienna events. Pętla <% events.forEach() %> generuje karty. Jeśli wynik pusty — wyświetlany error.

03Backend — 77 linii

Cały serwer to jeden plik index.js. Dwa endpointy: GET / zwraca pustą stronę, POST /submit wykonuje całą logikę.

// Formatowanie dat do ISO 8601 UTC — wymaganie Ticketmaster API
const getFormattedDate = (date) => {
    const pad = (n) => String(n).padStart(2, '0');

    return `${date.getUTCFullYear()}-${pad(date.getUTCMonth()+1)}-${pad(date.getUTCDate())}`
         + `T${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:00Z`;
};

const startDate = new Date();        // teraz
const endDate   = new Date();
endDate.setDate(startDate.getDate() + 7); // +7 dni

// Zapytanie do Ticketmaster Discovery API v2
const response = await axios.get(API_URL, {
    params: {
        apikey:        API_KEY,
        startDateTime: formattedStartDate,
        endDateTime:   formattedEndDate,
        city:          location,         // z req.body.location
    }
});

// Mapowanie odpowiedzi API → prosty obiekt
const eventsArray = response.data._embedded?.events || [];
const events = eventsArray.map((event) => ({
    eventName:     event.name,
    eventDate:     event.dates.start.localDate,
    eventLocation: event._embedded.venues[0].name,
    eventUrl:      event.url
}));

Obsługa błędów: blok try/catch przechwytuje wszelkie problemy — brak połączenia z API, miasto bez wyników, błąd autoryzacji. W każdym przypadku serwer renderuje stronę ze zmienną error zamiast crashować.

EJS — warunkowe renderowanie wyników

<% if (locals.events && locals.events.length > 0) { %>
  <section class="eventsList">
    <ul>
      <% events.forEach((event) => { %>
        <li>
          <span><%=event.eventName%></span>
          <p><%=event.eventDate%></p>
          <p><%=event.eventLocation%></p>
          <a href="<%=event.eventUrl%>" target="_blank">See more</a>
        </li>
      <% }); %>
    </ul>
  </section>
<% } else { %>
  <h1><%=error%></h1>  <!-- "No events found for this criteria." -->
<% } %>

04Ticketmaster Discovery API

Aplikacja używa publicznego endpointu GET /discovery/v2/events z Ticketmaster API. Odpowiedź jest zagnieżdżoną strukturą JSON — dane eventi siedzą w response.data._embedded.events, a dane o miejscu w event._embedded.venues[0]. Operator ?. (optional chaining) zabezpiecza przed błędem gdy API zwróci odpowiedź bez zagnieżdżonego klucza _embedded (np. gdy nie ma wyników).

  • Filtry datystartDateTime i endDateTime w formacie ISO 8601 UTC, obliczane dynamicznie per request
  • Filtr miasta — parametr city, Ticketmaster wyszukuje po nazwie w bazie venue
  • Klucz API — przekazywany jako parametr apikey w URL (standard Ticketmaster)
  • Odpowiedź — lista wydarzeń z nazwą, datą start, URL do strony biletu, osadzonym venue

05Struktura projektu

index.js
Cały backend — 77 linii. Express app, dwa endpointy, formatowanie dat, wywołanie API, mapowanie danych, obsługa błędów.
views/index.ejs
Jedyny widok — formularz wyszukiwania + warunkowe renderowanie listy wyników lub komunikatu błędu. Jedna strona, dwa stany.
public/styles/main.css
Pełne style UI — hero z gradient overlay na tle, karty wydarzeń w palecie bordo-pomarańczowej, responsywna siatka Flexbox.
public/styles/script.js
jQuery UX — obsługa stanu przycisku submit (data-wait), efekty fadeIn/hide dla komunikatów sukcesu i błędu.
public/images/
Zasoby graficznebackground.png jako tło hero sekcji, favicon.png.

06Stack technologiczny

Express.js
Framework HTTP — express.static() dla plików publicznych, bodyParser dla odczytu danych formularza POST.
EJS
Server-side rendering — szablony PHP-style z <%=</code> i pętlami <% forEach >. Zero JS po stronie klienta do budowania UI.
Axios
HTTP client — axios.get() z automatycznym parsowaniem JSON, obsługą parametrów URL i properly typed response.
Ticketmaster API
Discovery API v2 — publiczny endpoint wydarzeń z filtrowaniem po mieście i zakresie dat. Bezpłatne API z kluczem.
Node.js ESM
"type": "module" w package.json — nowoczesne import zamiast require() we wszystkich plikach projektu.
jQuery
UX formularza — obsługa stanu loading przycisku i animacje fadeIn/hide dla komunikatów. Ładowane z CDN.

07Czego dowodzi ten projekt

API integration

Pełny cykl: klucz API → parametry → Axios GET → parsowanie zagnieżdżonego JSON → mapowanie do widoku.

Asynchroniczny Node.js

async/await z blokiem try/catch — właściwa obsługa operacji I/O bez callback hell.

Formatowanie dat UTC

Ręczne budowanie dat ISO 8601 przez UTC gettery — świadomość timezone w API-world.

Optional chaining

_embedded?.events || [] — defensywne programowanie przy niestabilnych strukturach API.

SSR z EJS

Warunkowe renderowanie dwóch stanów (wyniki / błąd) w jednym szablonie bez JS po stronie klienta.

Projekt w 77 liniach

Skoncentrowany scope — jeden cel, minimalny kod, zero over-engineeringu. Działa.

Zobacz kod na GitHubie

77 linii backendu, jeden szablon EJS i integracja z Ticketmaster API — cały projekt w zasięgu wzroku.

Zobacz kod na GitHub
· · ·
Udostępnij jeśli spodobał Ci się mój projekt