Starting with asynchronous JS and promises I've learn to code almost alone, so I really need some ideas/advice, as it started to get really difficult to advance.
Because this is mostly server side, I can't provide a running snippet, but yet it's a short snippet.
Code
When I press a UI button, it fetches a resource, and this should create a set of list items. Simple enough:
const btn = document.getElementById(&quot;btn&quot;)
const ul = document.getElementById(&quot;ul&quot;)
const putItems = (items)=&gt;{items.forEach(item=&gt;ul.innerHTML=`
&lt;li&gt;${item.msg}&lt;/li&gt;`)}

btn.addEventListener(&quot;click&quot;, ()=&gt;{
    fetch(&quot;https://localhost:3000/todos&quot;)
        .then(res=&gt;res.json())
        .then(d=&gt;putItems(d))
        .catch(e=&gt;console.log(e))
})

On the server side, the main function and imports are:
const { MongoClient } = require(&quot;mongodb&quot;)
const cors = require('cors')
app.use(cors())

async function callDB(){   //get data from mongoDB
    const call = await MongoClient.connect( uri, {useNewUrlParser:true, useUnifiedTopology:true})
    let result
    try{
        result = await call
            .db(&quot;todos&quot;)
            .collection(&quot;items&quot;)
            .find({})
            .toArray()
    } catch(e){
        console.log(e)
    }

    return result;
}

app.get(&quot;/todos&quot;, cors(), (req, res)=&gt;{
    const items = callDB().then(d=&gt;res.json(d)).catch(e=&gt;console.log(e))
});

This code imports dotenv to hide my sensible parts, and uses express I removed those imports just to be concise.
Mainly, I'd like to know if my asynchronous practice makes sense, or not. And I'm also getting a CORS error, that couldn't fix after an hour. That would help too.
There is a problem regarding error handling: in callDB() you catch all exceptions and log them in the console without passing them on to the caller. Either you should rethrow the exception (or a modified version that is more helpful for the caller) or not catch it at all. Since the MongoClient.connect() can also fail, I would move it into the try/catch as well:
async function getDataFromMongoDB() {  // renamed so you don't need the comment
    try{
        const connection = await MongoClient.connect( uri, {
            useNewUrlParser: true,
            useUnifiedTopology: true
        });
        return await connection
            .db(&quot;todos&quot;)
            .collection(&quot;items&quot;)
            .find({})
            .toArray();
    } catch(e) {
        console.log(e);
        throw e; // or throw something else
    }
}

This would be even more concise if you would extract the creation of the connection into its own function. However, I think you would like to write the whole function in one expression after the return, you would have to write it like this:
return await (await getConnection()).db(&quot;todos&quot;)...

The first await is required to keep error handling in this function.
The request handler can also make use of async/await:
app.get(&quot;/todos&quot;, cors(), async (req, res)=&gt; {
    try {
        const response = await callDB();
        res.json(response);
    }
    catch (e) {
        console.log(e);
    }
});