DEV Community

Victor Del Carpio
Victor Del Carpio

Posted on • Updated on

Building an Art Gallery SPA with the Met Museum API

Introduction

For my Phase 1 final project at the Flatiron School's Software Engineering program, I developed an Art Gallery Single Page Application (SPA) utilizing the Metropolitan Museum of Art's API. This project allows users to explore artworks from specific artists in the Met's vast collection.

Background

In this project, I used JavaScript, HTML, and CSS to create the SPA. The key functionalities were implemented using event listeners and Fetch API for making asynchronous HTTP requests to the Met Museum's API endpoints.

Implementation

The core functionality of the application revolved around fetching data from the Met Museum's API endpoints. Here's how we achieved this:

API Integration

We made use of the Met Museum's API endpoints to gather information about artworks and artists. The primary endpoints utilized were:

Search Endpoint: https://collectionapi.metmuseum.org/public/collection/v1/search?q={query}
This endpoint allowed us to search for specific artists or artworks based on user input.

Object Details Endpoint: https://collectionapi.metmuseum.org/public/collection/v1/objects/{objectID}
With this endpoint, we could retrieve detailed information about individual artworks using their unique object IDs.

The following is how we use the API to collect the artwork information.

async function fetchArtworks(query) {
        const response = await fetch(`https://collectionapi.metmuseum.org/public/collection/v1/search?q=${query}`);
        const data = await response.json();
        const limitedObjectIDs = data.objectIDs.slice(0, 30);
        return limitedObjectIDs;
    }

async function fetchArtworkDetails(objectID) {
        const response = await fetch(`https://collectionapi.metmuseum.org/public/collection/v1/objects/${objectID}`);
        const data = await response.json();
        return data;
    }

async function displayArtworks(query) {
        const objectIDs = await fetchArtworks(query);
        artworksGrid.innerHTML = '';
        objectIDs.forEach(async objectID => {
            const artworkDetails = await fetchArtworkDetails(objectID);
            if (artworkDetails.primaryImageSmall) {
                const artworkImage = artworkDetails.primaryImageSmall;
                const artworkTitle = artworkDetails.title;

                const artworkElement = document.createElement('div');
                artworkElement.innerHTML = `
                <div class="card">
                    <img src="${artworkImage}" class="card-img-top" alt="${artworkTitle}">
                    <div class="card-body">
                        <h5 class="card-title">${artworkTitle}</h5>
                        <button class="btn btn-primary btn-sm view-details-btn" data-artwork-id="${objectID}">View Details</button>
                    </div>
                </div>
                `;
                artworksGrid.appendChild(artworkElement);
        }
    });
}
Enter fullscreen mode Exit fullscreen mode

Scraper Script

To populate our database file db.json with initial artwork data, we utilized a Python script. This script scraped data from the Met Museum's API using the requests library and saved it in JSON format. Here's a snippet of the scraper script:

import requests
import json

object_endpoint = "https://collectionapi.metmuseum.org/public/collection/v1/objects/"

def fetch_object_details(object_id):
    response = requests.get(object_endpoint + str(object_id))
    if response.status_code == 200:
        return response.json()
    else:
        return None

def fetch_and_save_objects(object_ids, filename):
    objects_data = {"artworks": []}
    for object_id in object_ids:
        object_details = fetch_object_details(object_id)
        if object_details:
            objects_data["artworks"].append(object_details)
        if len(objects_data["artworks"]) >= 100:
            break

    with open(filename, 'w') as f:
        json.dump(objects_data, f, indent=4)

if __name__ == "__main__":
    response = requests.get("https://collectionapi.metmuseum.org/public/collection/v1/search?medium=Paintings|Sculpture&q=europe")
    if response.status_code == 200:
        print(response.json()["total"])
        object_ids = response.json()["objectIDs"]
        fetch_and_save_objects(object_ids, "db.json")
        print("Objects fetched and saved successfully.")
    else:
        print("Failed to fetch objects.")

Enter fullscreen mode Exit fullscreen mode

Implementation

To start, I set up event listeners to handle user interactions such as submitting a search query or clicking on an artwork for more details. Here's a snippet of the JavaScript code:

// Event listeners for search functionality and modal display
searchForm.addEventListener('submit', function (event) {
    event.preventDefault();
    performSearch();
});

searchButton.addEventListener('click', function (event) {
    event.preventDefault();
    performSearch();
});

modal.addEventListener('click', function (event) {
    if (event.target && event.target.classList.contains('close')) {
        modal.style.display = 'none';
    }
});

artworksGrid.addEventListener('click', function (event) {
    if (event.target && event.target.classList.contains('view-details-btn')) {
        const objectID = event.target.getAttribute('data-artwork-id');
        displayModal(objectID);
    }
});

Enter fullscreen mode Exit fullscreen mode

This code sets up event listeners for search functionality, modal display, and artwork details viewing.

The following images is a demo of the website.
Image description
Image description

Top comments (1)

Collapse
 
jagedn profile image
Jorge Eψ=Ĥψ

hope next article will be about the API, it sound very interesting