javascriptpromisefetch-apieventbrite

Display event's venue name with JavaScript fetch and Eventbrite API


I am creating a university project to display events that are happening in Leeds. So far I have been able to show information about the event, but I also want to show the venue name which uses a different method.

I've managed to get a venue's name through the venue ID that's found in the event information, and these are showing correctly in the console. I now want to be able to show the venueName in the HTML template of ui.js. I think it is a simple problem, I just can't figure it out!

eventbrite.js

class EventBrite {
    constructor() {
        this.auth_token = 'Example';
        this.orderby = 'date';
        this.city = 'Leeds';
    }

    //Load Leeds events from API
    async loadAPI() {
        const initalEvents = await fetch(`https://www.eventbriteapi.com/v3/events/search/?sort_by=${this.orderby}&location.address=${this.city}&token=${this.auth_token}`);
    
        const events = await initalEvents.json();
    
        return {
            events
        }
    }

    async loadVenue(venueID) {
        const initalVenue = await fetch(`https://www.eventbriteapi.com/v3/venues/${venueID}/?token=${this.auth_token}`);
    
        const venue = await initalVenue.json();
    
        return venue;
    }
}

app.js

const eventbrite = new EventBrite();
const ui = new UI();
   
eventbrite.loadAPI()
    .then(events => {
        //Check for events
        const eventsList = events.events.events;
        
        //Print venue IDs
        for(let i = 0, l = eventsList.length; i < l; i++) {
            const venueID = eventsList[i].venue_id;
            
            eventbrite.loadVenue(venueID)
            .then(venue => {
                const venueName = venue.name;
            })
        }
        ui.displayEvents(eventsList);
    }
)

ui.js

class UI {
    constructor() {
        this.init();
    }
    init() {
        this.printCategories();
        
        this.result = document.getElementById('result');
    }
    
    //Display events
    displayEvents(events) {   
        //Build template
        let HTMLTemplate = '';
        events.forEach(eventInfo => {
            HTMLTemplate += `
                <div class="row">
                    <div class="column">
                        <p class="event">${eventInfo.name.text}</p>
                        <p class="event">${eventInfo.start.local}</p>
                    </div>
                </div>
            `;
        });
        this.result.innerHTML = HTMLTemplate;
    }
}

Solution

  • I think this should work:

    eventbrite.loadAPI()
        .then(async events => {
            //Check for events
            const eventsList = events.events.events;
    
            //Print venue IDs
            for(let i = 0, l = eventsList.length; i < l; i++) {
                const venueID = eventsList[i].venue_id;
    
                let venue = await eventbrite.loadVenue(venueID);
                eventsList[i].venue = venue.name
            }
            ui.displayEvents(eventsList);
        }
    )
    

    But note: This code is blocking. Venues are loaded once by once. To take them all, at the same time, you should look for a solution with Promise.all

    Edit: Example with Promise all

    eventbrite.loadAPI().then(events => {
        //Check for events
        const eventsList = events.events.events;
        let venuesPromises = eventsList.map(x => eventbrite.loadVenue(x.venue_id))
        return Promise.all(venuesPromises).then(x => {
            //x should contain all venues for the events. 
    
            const events_with_venues = 1 //TODO: merge events with venues
            return events_with_venues
        })
    })