Search code examples
javascriptasync-awaitpromiseappwrite

Having trouble with promise inside async function


having a real problem with getting this code to work. I have everything set up working great with Appwrite. I'm getting a response back from the server, but in my promise.then it finishes the other code and returns undefined from the login function. so then the post async function is sending a blank array in the try block. I've tried setting this code up every way I can think of but it never works. Sorry, i'm still trying to wrap my head around the promises and async js.

import { Appwrite } from 'appwrite';

export async function post({ locals, request }) {
const { email, password } = await request.json();

function login() {
    // add logic to authenticate user with external service here
    const sdk = new Appwrite();

    sdk
        .setEndpoint('https://') // API Endpoint
        .setProject('') // project ID
    ;

let promise = sdk.account.createSession(email, password);

    let userLogin;
    promise.then(function (response) {
    console.log(response); // Success
        userLogin = response.providerUid;
          console.log(userLogin);
    }, function (error) {
     console.log(error); // Failure
    });
    console.log('login.json.js', { email, password: !!password });

console.log(userLogin);
    return userLogin;
}

try {
    const user = login();
    locals.user = user;

    return {
        status: 200
    };
} catch (error) {
    const message = `Error in endpoint /api/login.json: ${error}`;
    return {
        status: 500,
        body: message
    };
}
}

Solution

  • You're returning userLogin in login before it's even populated in the asynchronous promise.then chain

    Also, since you're currently handling the rejection in your promise.then(onFulfilled, onRejected) that would mean any rejection is handled inside login and your try/catch (once written correctly) would never have an error to catch since login handled it already

    One more potential issue - if const { email, password } = await request.json(); rejects, then the error will be thrown to whatever called post - is that what you want? or did that also need to be handled inside post?

    Anyway here's how to fix your code:

    import { Appwrite } from 'appwrite';
    
    export async function post({ locals, request }) {
        // note: if this throws then the error will be handled by whatever calls `post`
        const { email, password } = await request.json();
    
        function login() {
            // add logic to authenticate user with external service here
            const sdk = new Appwrite();
    
            sdk
                .setEndpoint('https://') // API Endpoint
                .setProject('') // project ID
            ;
            const promise = sdk.account.createSession(email, password);
            return promise.then(function(response) {
                let userLogin = response.providerUid;
                return userLogin;
                // or without redundant `userLogin` variable
                // return response.providerUid;
            });
        }
    
        try {
            const user = await login();
            locals.user = user;
    
            return { status: 200 };
        } catch (error) {
            const message = `Error in endpoint /api/login.json: ${error}`;
            return { status: 500, body: message };
        }
    }
    

    Or, making login async

    import { Appwrite } from 'appwrite';
    
    export async function post({ locals, request }) {
        // note: if this throws then the error will be handled by whatever calls `post`
        const { email, password } = await request.json();
    
        async function login() {
            // add logic to authenticate user with external service here
            const sdk = new Appwrite();
    
            sdk
                .setEndpoint('https://') // API Endpoint
                .setProject('') // project ID
            ;
    
            let response = await sdk.account.createSession(email, password);
            let userLogin = response.providerUid;
            return userLogin;
        }
    
        try {
            const user = await login();
            locals.user = user;
    
            return {
                status: 200
            };
        } catch (error) {
            const message = `Error in endpoint /api/login.json: ${error}`;
            return {
                status: 500,
                body: message
            };
        }
    }
    

    Or, removing inner Login function completely

    import { Appwrite } from 'appwrite';
    
    export async function post({ locals, request }) {
        // note: if this throws then the error will be handled by whatever calls `post`
        const { email, password } = await request.json();
        try {
            const sdk = new Appwrite();
    
            sdk.setEndpoint('https://') // API Endpoint
                .setProject(''); // project ID
    
            const response = await sdk.account.createSession(email, password);
            console.log(response); // Success
            locals.user = response.providerUid;
            return { status: 200 };
        } catch (error) {
            const message = `Error in endpoint /api/login.json: ${error}`;
            return { status: 500, body: message };
        }
    }