0

Is it possible to return a value from a nested function? This is what I got so far and it doesnt work. In my code I am trying to return eventId from within the request.execute() function. I dont know if I am going in the right direction. Any help would be appreciated.

     function insertDate(dateFormat) {
        var eventId = "";
        gapi.client.load('calendar', 'v3', function() {                 // load the calendar api (version 3)
            var request = gapi.client.calendar.events.insert({
                'calendarId':       'primary',  // calendar ID
                "sendNotifications": true,
                "resource":         dateFormat      // pass event details with api call
            });

            // handle the response from our api call
            request.execute(function(resp) {
                if(resp.status=='confirmed') {
                    eventId = resp.id
                    console.log("eventId in execute: " + eventId)
                    console.log("successfully inserted")
                    return eventId
                } else {
                    console.log("failed to insert")
                }
                console.log(resp);
                console.log("2: " + resp.id);
            });
            return eventId
        });
        console.log("eventId on return: " + eventId)
        return eventId
    }

I put the function insertDate(dateFormat) in a loop and im adding the eventId which im trying to get from the request.execute() function into my eventIdArray as follows

var eventIdArray = [];
eventIdArray[i] = insertDate(dateFormat);
console.log("eventIdArray: " + eventIdArray[i]);
John
  • 97
  • 1
  • 7

2 Answers2

1

you can wrap the code in insertDate in promise and then resolve the eventId and then use async/await to fill the array. you need to do slight modification to your code

updated code of yours

function insertDate(dateFormat) {
    return new Promise((resolve, reject) => {
        var eventId = "";
        gapi.client.load('calendar', 'v3', function () {                 // load the calendar api (version 3)
            var request = gapi.client.calendar.events.insert({
                'calendarId': 'primary',  // calendar ID
                "sendNotifications": true,
                "resource": dateFormat      // pass event details with api call
            });

            // handle the response from our api call
            request.execute(function (resp) {
                if (resp.status == 'confirmed') {
                    eventId = resp.id
                    console.log("eventId in execute: " + eventId)
                    console.log("successfully inserted")
                    //  return eventId
                    resolve(eventId);
                } else {
                    console.log("failed to insert");
                    resolve(-1); // just for indication -1 means not confirmed      
                    //or reject(-1);
                }
                console.log(resp);
                console.log("2: " + resp.id);
            });
            // return eventId
        });
        console.log("eventId on return: " + eventId)
        
    });
}

then wrap the filling of the array in async/await,
note that you have to put async in front of the function that this loop contains in. I used fillEventIdArray just as an example for showing how to put async and use await inside it as await can't be used if the function does not contain async keyword

async fillEventIdArray(dateFormat) {
    var eventIdArray = [];
    //your for loop here and below is the code inside the for loop 
        const eventId = await insertDate(dateFormat)
        eventIdArray.push(eventId);
        console.log("eventIdArray: " + eventIdArray[eventIdArray.length - 1]);
}
mss
  • 1,423
  • 2
  • 9
  • 18
  • Is it also possible to put the async function inside my for loop. Right now I am trying to do that and I am getting a `Unresolved variable or type async ` and a `Unresolved function or method fillEventIdArray() ` error – John Jan 10 '21 at 19:21
  • @John, yes but you have to put async in front of the function that this loop contains in. I used fillEventIdArray just as an example for showing how to put async and use await inside it as await can't be used if the function does not contain async keyword – mss Jan 10 '21 at 19:24
1

No, you can't return a value from an asynchronous function call.

You can return promises, and use Promise.allSettled to wait until they're all done:

function insertDate(dateFormat) {
    return new Promise(function (resolve, reject) {
        // load the calendar api (version 3)
        gapi.client.load('calendar', 'v3', function() {
            var request = gapi.client.calendar.events.insert({
                'calendarId':       'primary',  // calendar ID
                "sendNotifications": true,
                "resource":         dateFormat      // pass event details with api call
            });

            // handle the response from our api call
            request.execute(function(resp) {
                if(resp.status=='confirmed') {
                    console.log("eventId in execute: " + resp.id)
                    console.log("successfully inserted")
                    resolve(resp.id);
                } else {
                    reject("failed to insert");
                }
            });
        });
    });
}

var dates = ['date1', 'date2', 'date3'];
var promises = [];

dates.forEach(function (date) {
    promises.push(insertDate(date);
});

Promise.allSettled(promises).then(function (results) {
    // 'results' is an array containing all the event IDs
});
Brother Woodrow
  • 6,092
  • 3
  • 18
  • 20