Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't createEvent* more than one event in loop #239

Closed
tcowin opened this issue Oct 2, 2015 · 11 comments
Closed

Can't createEvent* more than one event in loop #239

tcowin opened this issue Oct 2, 2015 · 11 comments

Comments

@tcowin
Copy link

tcowin commented Oct 2, 2015

Using the demo code in a loop, I can't create more than one(or two, sometimes) event. The second call to createEvent will issue a 'No calendar has been set." error(even though findEKCalendar has just printed "Calendar: Calendar" to the log). Trying more than 2, in general, results in nothing happening.

However, if I take the code in createEventWithOptions in Calendar.m out from behind the 'runInBackground' call,

/* [self.commandDelegate runInBackground: ^{ */

everything works perfectly, although a tad slower, obviously.

XCode 7.0.1
iOS 9.0.2
Cordova 5.3.1
"cordova-plugin-calendar": "4.4.3"

screen shot 2015-10-02 at 11 34 42 am

@ants-house
Copy link

Hey,
I'm discovering the same issue on iOS... Creating one event works perfectly, creating more than one event ends up in freezing or just doin' nothing. The same issue is for deleting events. Deleting one event works, deleting more than one doesn't work. On Android everything works as expected, on iOS everything is broken. I also restricted creating events to max. 64.

/** Create a single event
 * @param eventToCreate
 */
var createEvent = function (eventToCreate) {

    function onSuccess (argument) { 
        console.log(TAG + "Event created: ", argument); 
    }

    function onError (argument) {
        console.error(TAG + "Failed to create event", argument);
    }

    $ionicPlatform.ready(function() {
        window.plugins.calendar.createEventWithOptions(eventToCreate.title,    eventToCreate.location, eventToCreate.shortdescription, parseDate(eventToCreate.start), parseDate(eventToCreate.end), calendarOptions, onSuccess, onError);
    });
};

/**
 * Create a list of events
 * @param eventsToCreate
 * @returns {promise}
 */
var createEvents = function (eventsToCreate) {

    var deferred = $q.defer();

    for (var i = 0; i < eventsToCreate.length && i < 64; i++) {
        createEvent(eventsToCreate[i]);

        if(i == eventsToCreate.length-1 || i == 63) {
            // return number of created events
            deferred.resolve(i + 1);
        }
    }

    //TEST: this works
    //createEvent(eventsToCreate[0]);
    //deferred.resolve(1);

    return deferred.promise;
};

Maybe someone can help... I really need this so a workaround would be better than nothing.

Regards

@EddyVerbruggen
Copy link
Owner

Are you waiting for the first createEvent to return or are you just hammering the native code 64 times in a row?

@ants-house
Copy link

Well I'm running through the for loop which always calls the native code. I think it's not waiting for the first createEvent to finish. Is there a possibility to wait for it?

@tcowin
Copy link
Author

tcowin commented Feb 10, 2016

I did commit to fix this, but it’s not going to happen today. The problem is that it is not multithread safe. If you don’t run it in the background, then it will work fine in your context. You’d need to edit (hack cough, cough) src/ios/Calendar.m and comment out the loop that puts it in the background, like so:

in the function createEventWithOptions (lines 470 and 557 in the latest):

/* [self.commandDelegate runInBackground: ^{ */

/* }];*/

Thanks,

Tom

On Feb 10, 2016, at 7:42 AM, aaronprojects notifications@github.com wrote:

Well I'm running through the for loop which always calls the native code. I think it's not waiting for the first createEvent to finisch. Is there a possibility to wait for it?


Reply to this email directly or view it on GitHub #239 (comment).

@ants-house
Copy link

Got it :)! Calling the function recursively works really good!

/**
 * Create a list of events
 * @param eventsToCreate
 * @returns {promise}
 */
var createEvents = function (eventsToCreate) {

    var deferred = $q.defer();

    var createSingleEvent = function (events, i) {

        function onSuccess (argument) {
            createSingleEvent(events, i+1);     
        }

        function onError (argument) {
            deferred.reject({ message: argument });
        }

        $ionicPlatform.ready(function() {
            if (i < events.length) {
                window.plugins.calendar.createEventWithOptions(events[i].title, events[i].location, events[i].shortdescription, parseDate(events[i].start), parseDate(events[i].end), calendarOptions, onSuccess, onError);
            } else {
                deferred.resolve(events.length);
            }
        });
    };

    createSingleEvent(eventsToCreate, 0);

    return deferred.promise;
};

@EddyVerbruggen
Copy link
Owner

@aaronprojects That's the best way to do it as JS-Native calls to the Cordova bridge are async it's always best to wait for the callback to return.

Btw, by not running the Calendar in the background and hammering it in a loop you will block the UI which degrades performance.

@tcowin
Copy link
Author

tcowin commented Feb 10, 2016

Of course - that’s just a temporary workaround.

Javascript is asynchronous for speed, right? So if you suggest you have to wait until every call completes whether or not you need the result, you’re losing the advantage that it gives you…

Actually this is just another way of working around the problem of it not being able to handle two addEvent calls in a row. It will still run O(N). I’d still think the best solution would be that it’s made multithread safe? I’ll try to figure it out.

On Feb 10, 2016, at 10:50 AM, Eddy Verbruggen notifications@github.com wrote:

@aaronprojects https://github.com/aaronprojects That's the best way to do it as JS-Native calls to the Cordova bridge are async it's always best to wait for the callback to return.

Btw, by not running the Calendar in the background and hammering it in a loop you will block the UI which degrades performance.


Reply to this email directly or view it on GitHub #239 (comment).

@EddyVerbruggen
Copy link
Owner

@tcowin I know you did it is as a workaround / experiment, I'm just making sure others understand why it's implemented like it is.

I never created the plugin with threadsafeness in mind (that's why I added recurring events for making many events), but I can imagine there are valid cases for it. I don't know if whether or not the native calendar can be stressed that much so I'd rather not hammer it too much. Please consider that when trying to make it threadsafe and test it in a loop of 100+ invocations.

@tcowin
Copy link
Author

tcowin commented Feb 10, 2016

Sure - will do. The app that uses this for us syncs a set of distinct events for the user's conference itinerary, so the recurring is not an option. I'll look at what it would take to enable concurrent calls to addEvent, but maybe adding a call like addEvents, where you'd send in an array of events that the Objective C then iterates through might even be more performant.

@BhargavaNandan
Copy link

Hi this plugin is compatible with ios and android do we have any plugin to add calendar events for windows 10 devices using cordova

@unsama
Copy link

unsama commented Dec 5, 2017

**

> events: [
>                         {
>                             title: 'All Day Event',
>                             start: new Date(y, m, 1)
>                         },
>                         {
>                             id: 999,
>                             title: 'Repeating Event',
>                             start: new Date(y, m, d - 3, 16, 0),
>                             allDay: false,
>                             className: 'info'
>                         },
>                         {
>                             id: 999,
>                             title: 'Repeating Event',
>                             start: new Date(y, m, d + 4, 16, 0),
>                             allDay: false,
>                             className: 'info'
>                         },
>                         {
>                             title: 'Meeting',
>                             start: new Date(y, m, d, 10, 30),
>                             allDay: false,
>                             className: 'important'
>                         },
>                         {
>                             title: 'Lunch',
>                             start: new Date(y, m, d, 12, 0),
>                             end: new Date(y, m, d, 14, 0),
>                             allDay: false,
>                             className: 'important'
>                         },
>                         {
>                             title: 'Birthday Party',
>                             start: new Date(y, m, d + 1, 19, 0),
>                             end: new Date(y, m, d + 1, 22, 30),
>                             allDay: false,
>                         },
>                         {
>                             title: 'Click for Google',
>                             start: new Date(y, m, 28),
>                             end: new Date(y, m, 29),
>                             url: 'http://google.com/',
>                             className: 'success'
>                         }
>                     ],

**
here's my calendar events how i add in loop to post in database

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants