1

I am using angular 2 fullcalendar for one of my projects.everything works fine as long as i have the data ready before rendering the calender.If an event is triggered and data comes from backend,i am facing problem while using refetch function.I wil explain the code first and describe the error. I have installed

npm install fullcalendar

npm i angular2-fullcalendar

npm install jquery

npm install moment

in app.module.ts

i have imported

import {CalendarComponent} from "angular2-fullcalendar/src/calendar/calendar";

and i have declared in the declaration:[]

in html i am displaying calendar using

<div class="ui red segment" *ngIf="dataAvailable">
<angular2-fullcalendar [options]="calOptions" id="mycal" #mycal>
</angular2-fullcalendar>
</div>

In the component i have

import {CalendarComponent} from 'angular2-fullcalendar/src/calendar/calendar';
import {Options} from 'fullcalendar';

declare var $:any;
import * as moment from "moment";

and i have a refference to the tag like

 @ViewChild('mycal', { read: ElementRef }) myCal: ElementRef;

and my calendar configuration looks like

 calOptions: any = {
        height:350,
        defaultDate: moment(new Date(),'YYYY-MM-DD'),
        editable: false,
        stick:true,
        
        events:this.events,
        selectable:false,
        eventLimit: true, // allow "more" link when too many events
        header: {
                  left: 'month basicWeek basicDay',
                  center: 'title',
                  right: 'today prev,next'
                },
        displayEventTime: false,
        addEventSource:this.events,
        defaultView:'basicWeek',
       
        dayRender: (date, cell)=> {
                        var today = moment().format("YYYY-MM-DD");
                    //    today = moment(today).toDate();
                        
                        for(let item of this.holidayList){
                        
                        if(item.holidayDate === moment(date).format("YYYY-MM-DD"))
                        {
                         cell.css("background-color", "#e4564a");
                         
                        }
                        }
          } 
  };

Problem

Now when the new data comes if i try

$(this.myCal.nativeElement).fullCalendar('addEventSource', events)

It gives an error saying

Cannot read property 'nativeElement' of undefined

and if i try using

$('#mycal').fullCalendar('refetchEventSources',this.events);

it gives the error

caused by: $(...).fullCalendar is not a function

also if i use

$('angular2-fullcalendar').fullCalendar('refetchEventSources',this.events);

same error comes.What am i doing wrong??Please help.I am really stuck;

update

i did i did

@ViewChildren('mycal') cal: QueryList<CalendarComponent>

and after the new data comes,in the subscribe method i did,

this.cal.forEach(div => 
  {
    div.fullCalendar('removeEventSource', this.events);
     div.fullCalendar('addEventSource', this.events);
      div.fullCalendar('refetchEvents');

  }

Now it when the new data comes,old data is not removed from the view,but it is getting appended with the existing view.

Vikhyath Maiya
  • 3,122
  • 3
  • 34
  • 68
  • when are you calling `$(this.myCal.nativeElement)` ? – n00dl3 Aug 02 '17 at 08:43
  • i tried calling it after the data comes back from the server,and when isDataAvailable becomes true.Dint work.I tried calling it in ngAfterViewInit as wel,it dint work either – Vikhyath Maiya Aug 02 '17 at 08:44
  • you should try with `@ViewChildren()` `QueryList` class has a `changes` Observable that will notify when new elements arrive. – n00dl3 Aug 02 '17 at 08:48
  • may be a small example with respect to my code would help better as i am new to QueryList – Vikhyath Maiya Aug 02 '17 at 08:50
  • okay its kind of working now ,but the problem now is that ,it displaying the calendar with duplicate events.ie on first refresh it shows one event,on data change it shows two ,etc..any workaround ? – Vikhyath Maiya Aug 02 '17 at 10:16
  • adding the handler only once and not on every change ? – n00dl3 Aug 02 '17 at 10:25
  • I updated my question with what i did,where should add the handler method to make sure its executed only once – Vikhyath Maiya Aug 02 '17 at 13:43
  • Sorry ,was using the fullcalendar function wrongly,now its working fine..Please post an answer ,:.. – Vikhyath Maiya Aug 02 '17 at 13:52

2 Answers2

4

You are making it too complicated:

 @ViewChild('mycal') calendar : CalendarComponent;

then whenever you want to refresh you simply call:

this.calendar.fullCalendar('refetchEvents');

I don't know why to call ViewChildren to get an array of calendars when it seems you only have 1 in your html.

1

That's because you are using an *ngIf, your element might be present or not.

Instead of using @ViewChild('mycal') You should consider using @ViewChildren('myCal') and subscribe to QueryList.changes Observable:

@ViewChildren('myCal')
cal: QueryList < ElementRef > ;

ngAfterViewInit() {
  this.cal.changes
    .startWith(this.cal)
    .filter(list => list.length > 0)
    .subscribe(list => {
      console.log(list.first);
    })
}
n00dl3
  • 21,213
  • 7
  • 66
  • 76