await user input with async/await syntax
First of all, I would not use Promises to do event based programming.
It is not used like that, so your code will get harder to follow.
Also, I would advise you to split up your functions more and omit some comments that way.


//// MAIN ///////

let services = [
    { url: "x", label: "1" },
    { url: "y", label: "2" },
    { url: "z", label: "3" },
];

showServicesToUser(services);

//// END MAIN /////

const serviceList = document.querySelector("#serviceList");

function createButtonFromService(service) {
    let button = document.createElement("BUTTON");
    button.innerHTML = service.label;
    button.addEventListener("click", function () {
        document.dispatchEvent(
            new CustomEvent("serviceChosen", { detail: service })
        );
    });
    serviceList.appendChild(button);
}

function showServicesToUser(services) {
    if (services.length &lt; 1) return;

    serviceList.classList.remove("hidden");

    for (let service of services) {
        createButtonFromService(service);
    }
}

function chooseService(service) {
    console.log("service_chosen:", service);
    // ... go on....
}

document.addEventListener("serviceChosen", function (e) {
    serviceList.classList.add("hidden"); // hide again for we are done
    chooseService(e.detail);
}, { once: true });
.hidden{
  visibility: hidden
}
&lt;div id="serviceList" class="hidden"&gt;

&lt;/div&gt;



My proposed code above is written in a scripted kind of way, with a global variable (serviceList), but you could also write this all in a class (especially if you have more code), to make it more readable and reusable.


class ServiceChooser {
    serviceListSelector;
    serviceList;
    services;

    constructor(serviceListSelector, services) {
        this.serviceListSelector = serviceListSelector;
        this.services = services;

        this.serviceList = document.querySelector(serviceListSelector);
        
        document.addEventListener(`serviceChosen${this.serviceListSelector}`, (e) =&gt; this.chooseService(e.detail), { once: true });
    }

    createButtonFromService(service) {
        let button = document.createElement("BUTTON");

        button.innerHTML = service.label;
        button.addEventListener("click", () =&gt; {
            const event = new CustomEvent(`serviceChosen${this.serviceListSelector}`, { detail: service });
            document.dispatchEvent(event);
        });

        this.serviceList.appendChild(button);
    }

    chooseService(service) {
        this.serviceList.classList.add("hidden");
        console.log("service_chosen:", service);
        // ... go on....
    }
    
    showServicesToUser() {
        if (this.services.length &lt; 1) return;

        this.serviceList.classList.remove("hidden");

        for (let service of this.services) {
            this.createButtonFromService(service);
        }
    }
}

//// MAIN ///////

let services = [
    { url: "x", label: "1" },
    { url: "y", label: "2" },
    { url: "z", label: "3" },
];

const sc = new ServiceChooser('#serviceList', services);
sc.showServicesToUser();

// now you could add 2 service choosers, sperate from each other
const sc2 = new ServiceChooser('#serviceList2', services);
sc2.showServicesToUser();

//// END MAIN /////
.hidden{
  visibility: hidden
}
&lt;div id="serviceList" class="hidden"&gt;

&lt;/div&gt;
&lt;div id="serviceList2" class="hidden"&gt;

&lt;/div&gt;