Search code examples
javascriptqtqmlfor-in-loop

sending signal on when for/in loop has completed all iterations


I have an array of objects which I am using a for/in loop to manipulate into key/value pairs, which as it works writes each to a database.

My app is designed to send a push notification when the database is updated, which works as intended, but when there are multiple items in the loop it will send a notification per each of these objects (expected, but not so intended)

My simple loop code is:

for(var idx in multiSelectSaveArr) {
            calendarPage.saveCalendarMultiItem(time = multiSelectSaveArr[idx].creationDate, multiSelectSaveArr[idx])

        }

The purpose of this is that time will become the unique key, whilst the value is a JSON object.

my calendarPage.saveCalendarMultiItem is a signal to my dataModel, which is where the function to store the data is, so each iteration then calls a function which handles the database writing as an individual object

The nature of my loop is that sometimes it could contain 3 objects, other times 30 - it is a different number each time.

My Question Is

Is there a way I can signal the end of the loop, meaning once the final object has been iterated through to then only send a single notification?

Thanks for any help!


Solution

  • You can use Array.prototype.forEach to check the index and get the array value during iteration, once the idx is at the last but one index you call you notification function to signal the iteration is over:

    multiSelectSaveArr.forEach(function(val, idx){
       calendarPage.saveCalendarMultiItem(time = val.creationDate, val);
       if(idx === multiSelectSaveArr.length - 1) notificationCallback();
    }
    

    You can also do it using Array.prototype.entries and the for..of loop which is designed for iteration of an iterable like an array:

    for(const [idx, val] of multiSelectSaveArr.entries()){
       calendarPage.saveCalendarMultiItem(time = val.creationDate, val);
       if(idx === multiSelectSaveArr.length - 1) notificationCallback();
    }
    

    The reason I am calling the notificationCallback() inside the loop along with the if condition is because I assume you won't send the notification if the array is empty, if I placed the callback call after the loop it would've worked regardless and also it didn't require an if, but that would still call the notificationCallback() although the loop never ran.

    Do not use for..in loop to iterate over the array as it iterates over property values of an object (in this case an array object) in an unspecified order. See this answer for more details.