skip to Main Content

My "save" function asynchronously invokes my "uploadPart" function. "uploadPart" should save the part it is given, then return the generated part id. Within "uploadPart", I’m able to write the part id to the console – it is correct.

However, the "save" method’s "then" always receives "undefined".

Here’s the code I’m using.

async uploadPart(part: any): Promise<string> {            
                        
    const apiUrl = `${this.root}/api/Part/Upload`;

    // Saves the part and returns the generated part id.
    var partResult = await fetch(apiUrl,
        {
            method: "POST",
            credentials: "include",
            mode: "same-origin",
            body: part
        })
        .then((response) => {
            // get the generated part id - it's a string
            return response.text();
        });

    console.log("generated part id is " + partResult);

    return partResult;
},

async save(): Promise<string> {
            
    try {
        await this.validate()
            .then(await this.uploadPart(this.chosenFile), this.validationBad)
            .then((promise: Promise<String>) => {
                // Here, "promise" only shows "undefined"
                console.log("in try, part id is " + promise);
                return promise;
            });
    }
    catch (error) {
        console.log("in the catch!");
    }
    return;            
},

async validationBad(): Promise<string> {
    return Promise.reject();
},

2

Answers


  1. Chosen as BEST ANSWER

    A coworker found the issue.

    This...

    .then(await this.uploadPart(this.chosenFile), this.validationBad)
    

    ...should have been this...

    .then(() => this.uploadPart(this.chosenFile), this.validationBad)
    

    My incorrect way caused "this.uploadPart" to be evaluated outside the promise.

    Thanks everyone for your feedback.


  2. It’s returning undefined because you’re mixing async/await and promise chaining methods. The old way to handle promises was to call your promise and then chain the methods with .then for example: fetch(url).then(do something)

    With async/await, you set your function to be asynchronous and then await for the data to be returned. So in your case

    async save(): Promise<string> {
                
        try {
            await this.validate();
            const uploadPromise = await this.uploadPart(this.chosenFile), this.validationBad);
            console.log("in try, part id is " + uploadPromise);
            return uploadPromise;
    
        }
        catch (error) {
            console.log("in the catch!");
        }
        return;            
    },
    

    note this similar pattern can be applied to your upload function as well. Checkout the MDN docs or this article for a deeper dive

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search