angular-ui / ui-calendar

A complete AngularJS directive for the Arshaw FullCalendar.
http://angular-ui.github.io/ui-calendar/
MIT License
1.49k stars 728 forks source link

Unable to display the events fetched from database on the full calendar angular js directive #358

Closed HashtagPurvi closed 8 years ago

HashtagPurvi commented 8 years ago

I am new to AngularJS and have to incorporate an Admin LTE full calendar feature in my webapp. I am using Angular directive for the Arshaw FullCalendar JQuery plugin. Although I am able to display the calendar, I am not able to render the data fetched from the DB. Below is the code for the controller.

app.controller("calendarController", ["$scope", "displayCalendar", "dialogs", "$filter","$compile",               function ($scope, displayCalendar, dialogs, $filter,$compile) {

$scope.$parent.pageTitle = "Displays Reporting Period Start and End Dates";

$scope.form = {};
$scope.eventsources = [];
$scope.eventSources = [];

//Fetch Calendar Data
displayCalendar.getEvents().then(function (result) {
$scope.eventsources = result;
for (var i = 0; i < $scope.eventsources.length; i++) {

// Below 2 lines are for converting the dates in proper format                 
$scope.eventsources[i].start_date = $filter('date')    ($scope.eventsources[i].start_date, "yyyy-MM-dd");
 $scope.eventsources[i].end_date = $filter('date')($scope.eventsources[i].end_date, "yyyy-MM-dd");

 $scope.eventsources[i] =
        {
            title: $scope.eventsources[i].name,
               start: $scope.eventsources[i].start_date,
               end: $scope.eventsources[i].end_date,
              allDay: false              
        };

$scope.uiConfig = {
calendar: {
    height: 450,
    editable: true,
    header: {
        left:   'title',
        center: '',
        right:  'today prev,next'
    }
 };

 $scope.eventSources = [$scope.eventsources];
 }]);

In the above code, displayCalendar is the service which gets the data from the DB and getEvents() function is called to get the data in controller. The variable "result" contains the DB data and is then assigned to eventsources. My issue is I want to use this $scope.eventsources outside the getEvents() function so that I can use it to display the events on to the calendar. But when I do console.log(eventsources) outside the getEvents() it gives undefined. I did some digging and that helped me to understand that the getEvents() return the results late and that is the reason that when I console.log(eventsources) outside the function it is unassigned as by that time getEvents() has not returned anything. Please help m badly stuck. How can I make sure that first getEvents() should return the data and then the code below the function should get executed.

HashtagPurvi commented 8 years ago

Followed @jdnichollsc Solution given below and the events get rendered now.

uiCalendarConfig.calendars.myCalendar.fullCalendar('removeEvents'); uiCalendarConfig.calendars.myCalendar.fullCalendar('addEventSource', events);

paperlambda commented 8 years ago

@HashtagPurvi where did exactly you put those rows above? same issue here

HashtagPurvi commented 8 years ago

Just after when I assigned the $scope.eventSources. screenshot 2016-06-23 12 10 37

Lemme know if this helps !

paperlambda commented 8 years ago

@HashtagPurvi thank you, i've tried that before, it's not working. i actually managed to fix my problem by pushing the event (again) when the $scope is updated

avastamin commented 8 years ago

This is how I used and it's working:

` $scope.myevents = function(start, end, timezone, callback) {

    eventsModel.get() // eventsModel called to get events from Google calendar
        .success(function(data) {
            var events = [];

            angular.forEach(data,function(event,key){
                $scope.events.push({
                    id: event.id,
                    title: event.time,
                    start: event.start
                });
            });

                callback(events);
        });

}

$scope.eventSources = [$scope.events, $scope.myevents]; `

sachinvrg commented 8 years ago

@avastamin I am getting 'source is undefined' and $scope.event is undefined , can you please let me know what is wrong with my codes ? ` $scope.eventList = function(callback) {

    service.event_list($scope, function (response) {
        var events = [];
        angular.forEach(response,function(event,key){
            $scope.events.push({
                id: event.id,
                title: event.name,
                start: event.start_date_time
            });
        });
        callback(events);
    });
}
$scope.eventSources = [$scope.events, $scope.eventList];` 

I am using your directions , I also tried @HashtagPurvi solution but couldn't success , please help!!!

paperlambda commented 8 years ago

@sachinvrg maybe you should defined it first outside the function/service.

sachinvrg commented 8 years ago

@revzankamarullah I've tried $scope.event = [] but it is not working, can you please share working codes if you have? I have also posted question at stackoverflow but still waiting for answer http://stackoverflow.com/questions/38989253/how-to-display-the-events-fetched-from-database-on-the-full-calendar-angular-js?noredirect=1#comment65331119_38989253

paperlambda commented 8 years ago

@sachinvrg what about $scope.eventSources ? Have you define that? if you haven't, define it as an object. Because i thought the calendar initialized before the request to the server done. After that you could watch $scope.eventSources and push the array.

sachinvrg commented 8 years ago

@revzankamarullah - I've posted full code base here - http://stackoverflow.com/questions/38989253/how-to-display-the-events-fetched-from-database-on-the-full-calendar-angular-js?noredirect=1#comment65331119_38989253 Can you please check it and let me know what is wrong? Thanks much for your response.

paperlambda commented 8 years ago

@sachinvrg i see $scope.eventSource instead of $scope.eventSources on your code

avastamin commented 8 years ago

See my code here: http://stackoverflow.com/a/38990209/1960558

it's working for me

sachinvrg commented 8 years ago

I don't know what I am missing here , but I paste your code - `app.controller('eventController', function($scope,$http, factoryInfo, service, $routeParams, Lightbox, $route, Upload, $compile) {

$scope.events = [];
$scope.calendarConfig = {
    calendar: {
        allDaySlot: false,
        timezone: 'local',
        editable: true,
        lang: 'de',
        header: {
            left:   'title',
            center: 'Custom text',
            right:  'today prev,next'
        },
        eventClick: $scope.eventClick,
        eventResizeStop: $scope.alertResize,
        eventDragStop: $scope.alertDrag,
        eventRender: $scope.eventRender,
        dayClick: $scope.dayClick
    }
};

$scope.myevents = function(start, end, timezone, callback) {

    service.event_list($scope, function (response) {

        //  $rootScope.myobject = data;

        var events = [];

        angular.forEach(response,function(event,key){
            $scope.events.push({
                id: event.id,
                title: event.name,
                start: event.start_date_time
            });
        });

        callback(events);
    });

}
$scope.eventSources = [$scope.events,$scope.myevents];

});`

In HTML view <div ng-controller="eventController" data-ng-init="eventList(callback())" class="main-container"> and <div class="calendar" ng-model="eventSources" calendar="myCalendar1" ui-calendar="uiConfig.calendar"></div>

avastamin commented 8 years ago

I don't think, data-ng-init will work here....

sachinvrg commented 8 years ago

I tried after remove it but didn't work , I checked in console while use your codes , it is throwing eventProps.start is undefined

sachinvrg commented 8 years ago

Finally these codes worked for me, thanks much all of you!!! `app.controller('eventController', function($scope,$http, factoryInfo, service) {

$scope.events = [];
$scope.calendarConfig = {
    calendar: {
        allDaySlot: false,
        timezone: 'local',
        editable: true,
        lang: 'de',
        header: {
            left:   'title',
            center: 'Custom text',
            right:  'today prev,next'
        },
        eventClick: $scope.eventClick,
        eventResizeStop: $scope.alertResize,
        eventDragStop: $scope.alertDrag,
        eventRender: $scope.eventRender,
        dayClick: $scope.dayClick
    }
};

$scope.myevents = function(start, end, timezone, callback) {

    service.event_list($scope, function (response) {

        var events = [];

        for (var i = 0; i < response.result.length; i++) {
            $scope.events.push({
                id: response.result[i].id,
                title: response.result[i].name,
                start: response.result[i].start_date_time
            });
        }

        callback(events);
    });
}
$scope.eventSources = [$scope.events,$scope.myevents];

});`

franklindner commented 7 years ago

I tried everything said in that thread but I am unable to get the events to render.

screen shot 2017-06-02 at 10 30 55

My HTML (Jade):

div(calendar="bookingCalendar"
      ui-calendar="calendarConfig.calendar"
      data-ng-show="viewType === 'calendar'" 
      data-ng-model="eventSources")

My Controller Logic:

        /**
        * CALENDAR CODE
        */
        $scope.booking = {
            events: []
        };
        /* event source that calls a function on every view switch */
        $scope.getEvents = function (start, end, timezone, callback) {

            console.log('Getting events for START: ' + start + ' and END: ' + end);

            $scope.booking.events = [];

            var queryParams = {
                from: moment(start).toDate().getTime(),
                to: moment(end).toDate().getTime()
            };

            ServiceBooking.getBookings(queryParams).then(

                function (response) {

                    for (var i = 0; i < response.bookings.length; i++) {

                        var bookingEvent = response.bookings[i];

                        var title = (bookingEvent.amenityName ? bookingEvent.amenityName : bookingEvent.serviceName) + ' - ' + bookingEvent.residentName;

                        $scope.booking.events.push({
                            title: title,
                            start: moment(bookingEvent.startTimestamp).toDate(),
                            end: moment(bookingEvent.endTimestamp).toDate(),
                            allDay: false,
                            stick: true,
                            url: '//google.com/',
                        });
                    }
                    uiCalendarConfig.calendars.bookingCalendar.fullCalendar('removeEvents');
                    uiCalendarConfig.calendars.bookingCalendar.fullCalendar('addEventSource', $scope.booking.events);
                    callback($scope.booking.events);
                }
            );
        };

        /* event sources array*/
        $scope.eventSources = [$scope.booking.events, $scope.getEvents];

        /* config object */
        $scope.calendarConfig = {
            calendar:{
                height: 450,
                timezone: 'local',
                editable: true,
                header:{
                    left: 'title',
                    center: '',
                    right: 'today prev,next'
                },
                eventClick: $scope.eventClick,
                eventResizeStop: $scope.alertResize,
                eventDragStop: $scope.alertDrag,
                eventRender: $scope.eventRender,
                dayClick: $scope.dayClick,
                viewRender: function(view, element) {
                    console.log("View Changed: ", view.start.format('YYYY-MM-DD HH:mm'), view.end.format('YYYY-MM-DD HH:mm'));
                }
            }
        };
avastamin commented 7 years ago

why don't you try exactly the way I did here: https://stackoverflow.com/a/38990209/1960558 if works then refactor your code.

Otherwise create a online fiddle so that we can check it online.

Thanks

franklindner commented 7 years ago

@avastamin tried exactly that still no luck. I can see both $scope.events and $scope.eventSources being changed when I move between months but no event is rendered.

avastamin commented 7 years ago

Re-order the position of the code:

` $scope.booking = { events: [] };

   $scope.calendarConfig = {
        calendar:{
            height: 450,
            timezone: 'local',
            editable: true,
            header:{
                left: 'title',
                center: '',
                right: 'today prev,next'
            },
            eventClick: $scope.eventClick,
            eventResizeStop: $scope.alertResize,
            eventDragStop: $scope.alertDrag,
            eventRender: $scope.eventRender,
            dayClick: $scope.dayClick,
            viewRender: function(view, element) {
                console.log("View Changed: ", view.start.format('YYYY-MM-DD HH:mm'), view.end.format('YYYY-MM-DD HH:mm'));
            }
        }
    };

/ event source that calls a function on every view switch / $scope.getEvents = function (start, end, timezone, callback) {

        console.log('Getting events for START: ' + start + ' and END: ' + end);

        $scope.booking.events = [];

        var queryParams = {
            from: moment(start).toDate().getTime(),
            to: moment(end).toDate().getTime()
        };

        ServiceBooking.getBookings(queryParams).then(

            function (response) {

                for (var i = 0; i < response.bookings.length; i++) {

                    var bookingEvent = response.bookings[i];

                    var title = (bookingEvent.amenityName ? bookingEvent.amenityName : bookingEvent.serviceName) + ' - ' + bookingEvent.residentName;

                    $scope.booking.events.push({
                        title: title,
                        start: moment(bookingEvent.startTimestamp).toDate(),
                        end: moment(bookingEvent.endTimestamp).toDate(),
                        allDay: false,
                        stick: true,
                        url: '//google.com/',
                    });
                }
                uiCalendarConfig.calendars.bookingCalendar.fullCalendar('removeEvents');
                uiCalendarConfig.calendars.bookingCalendar.fullCalendar('addEventSource', $scope.booking.events);
                callback($scope.booking.events);
            }
        );
    };

    /* event sources array*/
    $scope.eventSources = [$scope.booking.events, $scope.getEvents];`