0

I have this function that should return only the raw statistics from a youtube channel using the youtube v3 data api

var getChannelStats = function (chId) {
    return new Promise((resolve, reject) => {
        google.youtube("v3").channels.list({
            key: token,
            part: "statistics",
            id: chId,
        }).then(res => {
            resolve(res.data?.items?.[0]?.statistics)
        })
    })
};

And then I want to have multiple functions to only return a certain information from the stats

async function getChannelViews(channelId) {
    return new Promise(resolve => {
        getChannelStats(channelId).then(res => { resolve(res.viewCount) })
    })
}

Is there a better way of implementing this?

Timon
  • 17
  • 4
  • 4
    You are using the promise constructor unnecessarily - don't create a promise when you already have one. `getChannelViews` should just return `getChannelStats(...)` and `getChannelStats` should just return `google.youtube(...).channels.list(....)` – Yousaf May 21 '21 at 09:15
  • 2
    [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/q/23803743) – VLAZ May 21 '21 at 09:18
  • 1
    @Yousaf also, `getChannelViews` probably shouldn't be `async`. Or if it is, it could at least use `await` in the body: `const res = await getChannelStats(channelId); return res.viewCount;` – VLAZ May 21 '21 at 09:20
  • 1
    I guess you could just do `const getChannelViews = async (channelId) => (await getChannelStats(channelId)).viewCount` – Jeremy Thille May 21 '21 at 09:21
  • 1
    try await keyword since you are already using async keyword – TrickOrTreat May 21 '21 at 09:21
  • 1
    @VLAZ yes, you are right. There's lots of unnecessary promise creation in OP's code. – Yousaf May 21 '21 at 09:22
  • Thanks I tried using await but forgot the brackets around the await I ended up using: ` const getChannelViews = async (channelId) => { return (await getChannelStats(channelId)).viewCount } ` – Timon May 21 '21 at 09:29

1 Answers1

3

If you can chain .then() to something, in general it means it's already a Promise. So, there's no need wrapping that Promise inside another Promise, and resolve the outer Promise when the inner Promise resolves, it's overkill and inelegant.

Besides, instead of using .then(), it's easier to use await :

const getChannelStats = async (chId) => {
    const res = await google.youtube("v3").channels.list({
        key: token,
        part: "statistics",
        id: chId,
    })

    return res.data?.items?.[0]?.statistics // This is a Promise. Async functions always return Promises. So you can do await getChannelStats()
}

const getChannelViews = async (channelId) => (await getChannelStats(channelId)).viewCount;

const viewsCount = await getChannelViews(someChannelId);
console.log("viewsCount = ", viewsCount);
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63