Search code examples
dartdart-js-interop

Calling a javascript function, which is passed as a parameter from a javascript library


I'm currently trying to implement the fullcalendar javascript library into an angular 2 dart webapp. I'm having problems porting this javascript code to dart though:

$('#fullCalendar').fullCalendar(
{
    events: function(start, end, timezone, callback) {
        var generated_events=[
        {
            title  : 'test',
            start  : '2016-08-08'
        }];
        callback(generated_events);
    },
    allDaySlot: false
    //More options can go here
});

I've gotten as far as being able to pass a dart function to the events parameter with this code:

context.callMethod(r'$',['#fullCalendar'])
        .callMethod('fullCalendar',[new JsObject.jsify({
        'events': (start, end, timezone, callback){
            print("called!");
            List<FullCalendarEvent> generated_events= [
                new FullCalendarEvent(title: "test", start: "2016-08-08")
            ];
            try{
                callback(generated_events);
            }catch(exception,stackTrace){
                print("Caught exception!");
                print(exception);
                print(stackTrace);
            }
        },
        'allDaySlot': false
        //more options can go here
    })]);

Where the FullCalendarEvent is a simple anoymous class structure:

@JS()
@anonymous
class FullCalendarEvent{
    external String get title;
    external set title(String v);

    external String get start;
    external set start(String v);

    external factory FullCalendarEvent({
        String title,
        String start
    });
}

However the callback(generated_events); throws this exception:

NoSuchMethodError: method not found: 'call$1' (callback.call$1 is not a function)

Edit:

With the help of Günter's replies I managed to fix the problem. Instead of doing callback(generated_events); I instead use callback.apply([generated_events]); Additionally instead of using

List<FullCalendarEvent> generated_events= [
    new FullCalendarEvent(title: "test", start: "2016-08-08")
];

I instead use:

var generated_events = new JsObject.jsify([{'title':'test','start':'2016-08-08'}]);

My working code looks like this:

context.callMethod(r'$',['#fullCalendar'])
    .callMethod('fullCalendar',[new JsObject.jsify({
        'events': (start, end, timezone, callback){
            print("called!");
            var generated_events = new JsObject.jsify([{'title':'test','start':'2016-08-08'}]);
            try{
                callback.apply([generated_events]);
            }catch(exception,stackTrace){
                print("Caught exception!");
                print(exception);
                print(stackTrace);
            }
        },
        'allDaySlot': false
        //more options can go here
    })]);

Solution

  • A JS function should be callable with

    callback.apply([gen‌​erated_events])