zodern/meteor-relay

Async Method double promise

timsun28 opened this issue · 2 comments

I'm having an issue where I need to run some async code in a method. To get this working, I've added async in front of the run function and used await with the async code.

import fetch from "node-fetch";

export const asyncMethod = createMethod({
    name: "method.async",
    schema: z.object({ param: z.string() }),
    async run() {
        // fetch github stars for a repo
        const response = await fetch(
            "https://api.github.com/repos/zodern/meteor-relay"
        );
        const json = await response.json();
        return json.stargazers_count;
    },
});

The asyncMethod has a return value as follows: Promise<Promise>
This causes the res when calling the method on the client to have a value of Promise while in reality it is not.

asyncMethod({ param: "test" }).then((res) => {
     console.log({ res });
});

In this case, res equals 15 and not a promise.

Is there a way to fix this is issue on my side, or is this a bug in the package?

If I understand correctly, this is only an issue with the types, and the code runs correctly. We probably need to change the return type from Promise<T> to Promise<Awaited<T>>.

Yes, it's correct that this is only a types issue. I think that the confusing part is that both run() and async run() will both return the given value. So with the current types it adds another Promise around the return type when async is used in front of the run() function, but this should not be the case.

I'm not sure what would happen if you only use run() without async and the return type includes Awaited.

We could possibly add a test with the wait100 and fastMethod methods in your tests to see if the given return type is as expected.