What is the best way to enable external events for Fullcalendar in an Angular environment?

Struggling to integrate external events with Fullcalendar and Angular. Admittedly, I am new to Angular and there are aspects that still elude me.

Fullcalendar provides a guide on setting up with Angular, available here. Initially, I managed to set up the main calendar successfully following this guide. However, my progress hit a snag when I attempted to add external events to the calendar. There is mention of a Draggable object that needs to be used, along with some documentation on using it with Typescript. Trying to make sense of how to incorporate this into the calendar setup has been quite perplexing for me.

My search for resources on how to implement draggables for Fullcalendar in an Angular environment pointed me to a single code example found here. Despite creating an external-events component to manage this, integrating their Draggable code into a new component continues to give me trouble. This particular aspect presents a significant challenge for me.

new Draggable(this.external.nativeElement, {
  itemSelector: '.fc-event',
  eventData: function(eventEl) {
    return {
      title: eventEl.innerText
    };
  }
});

I have developed an external-events component for handling these functionalities, but whether I place it in the same component as where the calendar was created or not, I encounter the same error. Below is the snippet from external-events.component.html:

<div class="external-event-list">
  <div class="fc-event" *ngFor="let job of jobs" data-event="{{job}}" #external>{{job.customer.first_name}} {{job.customer.last_name}}</div>
</div>

Here is what external-events.component.ts looks like:

import {AfterContentInit, Component, ElementRef, OnInit, ViewChildren} from '@angular/core';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {Draggable} from '@fullcalendar/interaction';


@Component({
  selector: 'app-external-events',
  templateUrl: './external-events.component.html',
  styleUrls: ['./external-events.component.css'],
})

export class ExternalEventsComponent implements OnInit, AfterContentInit {
  @ViewChildren('external', {static: true}) external: any;
  jobs: string [];

  constructor(private httpService: HttpClient) {
  }

  ngOnInit(): void {
    this.httpService.get('http://127.0.0.1:7000/api/schedule/unscheduled/?format=json').subscribe(
      (data) => {
        this.jobs = data as string [];
      },
      (err: HttpErrorResponse) => {
        console.log(err.message);
      },
    );
  }

  ngAfterViewInit(): void {
    this.external = new ElementRef('external');
    new Draggable(this.external.nativeElement, {
      itemSelector: '.fc-event',
      eventData: (eventEl) => {
        console.log(eventEl);
        return {
          title: eventEl.innerText,
        };
      },
    });
  }
}

The persistent error I keep encountering is

containerEl.addEventListener is not a function
triggered by the call to Draggable. No instance of containerEl exists in my code, leading me to believe it might be part of the base Fullcalendar code attempting to attach a listener to the calendar element but failing to locate it.

How can I rectify this issue and get the draggable feature to work effectively?

EDIT Below is the stack trace for the aforementioned error (Line 34 of external-events.component.ts is where the Draggable function is invoked):

ERROR TypeError: containerEl.addEventListener is not a function
    at new PointerDragging (main.js:125)
    at new FeaturefulElementDragging (main.js:780)
    at new ExternalDraggable (main.js:2031)
    at ExternalEventsComponent.ngAfterViewInit (external-events.component.ts:34)
    at callHook (core.js:2481)
    at callHooks (core.js:2451)
    at executeInitAndCheckHooks (core.js:2403)
    at refreshView (core.js:9242)
    at refreshComponent (core.js:10324)
    at refreshChildComponents (core.js:8968)
defaultErrorLogger  @   core.js:6006
handleError @   core.js:6054
(anonymous) @   core.js:29191
invoke  @   zone-evergreen.js:364
run @   zone-evergreen.js:123
runOutsideAngular   @   core.js:28195
tick    @   core.js:29191
(anonymous) @   core.js:29070
invoke  @   zone-evergreen.js:364
onInvoke    @   core.js:28267
invoke  @   zone-evergreen.js:363
run @   zone-evergreen.js:123
run @   core.js:28150
next    @   core.js:29069
schedulerFn @   core.js:25632 
__tryOrUnsub    @   Subscriber.js:183
next    @   Subscriber.js:122
_next   @   Subscriber.js:72
next    @   Subscriber.js:49
next    @   Subject.js:39
emit    @   core.js:25622
checkStable @   core.js:28203
onHasTask   @   core.js:28281
hasTask @   zone-evergreen.js:419
_updateTaskCount    @   zone-evergreen.js:440
_updateTaskCount    @   zone-evergreen.js:263
runTask @   zone-evergreen.js:184
drainMicroTaskQueue @   zone-evergreen.js:569
Promise.then (async)        
scheduleMicroTask   @   zone-evergreen.js:552
scheduleTask    @   zone-evergreen.js:388
scheduleTask    @   zone-evergreen.js:210
scheduleMicroTask   @   zone-evergreen.js:230
scheduleResolveOrReject @   zone-evergreen.js:847
then    @   zone-evergreen.js:979
bootstrapModule @   core.js:28855
zUnb    @   main.ts:11
__webpack_require__ @   bootstrap:79
0   @   scheduler.component.ts:18
__webpack_require__ @   bootstrap:79
checkDeferredModules    @   bootstrap:45
webpackJsonpCallback    @   bootstrap:32
(anonymous) @   main.js:1

Answer №1

Alright, I was able to solve the issue after realizing my mistakes.

Initially, I misplaced the property decorator within the HTML template. The #element should have been placed on the parent div element like so:

<div class="external-event-list" #external>
  <div class="fc-event" *ngFor="let job of jobs" data-event="{{job}}">{{job.customer.first_name}} {{job.customer.last_name}}</div>
</div>

I wrongly assumed that Draggable required access to individual draggable items, but it actually needed the parent container where it could find the draggables using the .fc-event selector.

For those facing a similar issue in the future, here is the external events component code:

import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {Draggable} from '@fullcalendar/interaction';

@Component({
  selector: 'app-external-events',
  templateUrl: './external-events.component.html',
  styleUrls: ['./external-events.component.css'],
})

export class ExternalEventsComponent implements OnInit, AfterViewInit {
  @ViewChild('external') external: ElementRef;
  jobs: string [];

  constructor(private httpService: HttpClient) {}

  ngOnInit(): void {
    this.httpService.get('http://127.0.0.1:7000/api/schedule/unscheduled/?format=json').subscribe(
      (data) => {
        this.jobs = data as string [];
      },
      (err: HttpErrorResponse) => {
        console.log(err.message);
      },
    );
  }

  ngAfterViewInit(): void {
    new Draggable(this.external.nativeElement, {
      itemSelector: '.fc-event',
      eventData: (eventEl) => {
         return {
          title: eventEl.innerText,
        };
      },
    });
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to retrieve the data from a specific section when a checkbox is selected in Angular 2?

When I select a checkbox for any section and then click the submit button, I want to display the details of that section in the console. Can someone assist me with this? **Stackblitz link:** : https://stackblitz.com/edit/angular-q7y8k1?file=src%2Fapp%2Fa ...

Having trouble with the yAxis in HighCharts on Angular 8? FireFox and IE causing issues?

Hey there! Currently, I am using "highcharts 8.0.0" along with "highcharts-angular 2.4.0" in combination with Angular 8. While the line charts are displaying perfectly fine on Google Chrome, I seem to be facing an issue with Firefox. The problem is that t ...

Exploring Angular 2/4: Unpacking the Process of Accessing API Data Using Tokens

Hello there, I am trying to retrieve API data with a token using Angular 2/4. Below is the code I have written: import { Component, ViewEncapsulation } from '@angular/core'; import { Http, Response } from '@angular/http'; import &apos ...

I am currently leveraging Angular 17, but I have yet to enable Vite. Can anyone guide me on

Despite having the most recent version of NX and Angular, my app has not yet integrated Vite. I've come across online suggestions on how to enable it, but none of them make sense to me because my project doesn't have an angular.json file. Instead ...

Can the Date class be expanded by overloading the constructor method?

In my dataset, there are dates in different formats that Typescript doesn't recognize. To address this issue, I developed a "safeDateParse" function to handle extended conversions and modified the Date.parse() method accordingly. /** Custom overload ...

Delete a Leaflet polyline connecting two markers using Angular

When utilizing the interval to update JSON data coordinates, a connection path appears between the last and first points on the original data path. Is there a way to eliminate this "connection path" that connects the last and first marker points? Code : ...

What is the best way to restrict a Generic type within a Typescript Function Interface?

Imagine having the following interface definitions: interface SomeInterface {a: string; b: number} interface SomeFunction<T> {(arg: T) :T} The usage of the function interface can be demonstrated like this: const myFun: SomeFunction<string> = a ...

Accessing element from view within controller in Ionic version 3.5

I am currently working on a project in Ionic 3.5, where I need to implement a feature that automatically loads an image "ad" after the page finishes loading. Right now, clicking a button successfully displays the image. However, I want this functionality ...

Encountered an 'angular client server error' when attempting to connect to the netty-socket.io server

My attempts to establish a connection between my Angular application and a Java socket server using netty-socket.io are failing... Whenever I try, I encounter the following error under 'connect_error': Error: server error at Socket.onPacket ...

Efficiently setting HttpParams like HttpHeaders in Angular: A streamlined approach

Having recently made the switch from using the old Http API to the new HttpClient API in Angular, I found myself needing to work with HttpHeaders and HttpParams. So far, everything is going smoothly. However, the examples I came across for declarations see ...

Issue with Angular MatSelect Losing Selected Value in Reactive Form Upon Submission

Working on an Angular project with a reactive form that features a <mat-select> for selecting cities. Although the dropdown functions properly in displaying and allowing city selection, there's a problem when attempting to submit the form: the s ...

Developing with TypeScript - Utilizing the <reference path="....."> directive

Recently, I encountered an issue while adding a plugin to the TypeScript compiler. After including my code and compiling tsc.ts, it compiled without any errors. However, when I attempted to run it, I noticed that some variables declared in io.ts were missi ...

"Angular application experiencing navigation blockage due to multiple concurrent HTTP requests using RxJS - Implementation of priority-based cancel queue

I've come across similar threads, but I have yet to find a suitable solution for my specific issue. Situation: Currently, I'm navigating on both the server side and client side simultaneously. This entails that every frontend navigation using ro ...

React and MaterialUI Chrome Extension - Data did not populate in the table

Currently, I am in the process of developing a browser extension. My main challenge lies in displaying data within a table that has been created using MaterialUI and React. Despite not encountering any errors, everything else renders perfectly. The console ...

invoke a method from a different class within the same component file

I am facing a situation where I have 2 classes within the same component.ts file. One class is responsible for embedding the Doc blot, while the other class serves as the main component class. I need to call a function that resides in the component class f ...

Tips on deactivating a div when a checkbox is selected

I am currently working with a checkbox element in my code: <md-checkbox checked.bind="addEventCommand.allDay" change.delegate="allday()">All Day</md-checkbox> When the above checkbox is true, I want to disable the following ...

Using @carbon/react in conjunction with Next.js version 13 leads to unconventional styling

Here's what I did to set up my Next.js application: npx create-next-app@latest I then installed the necessary package using: npm i -S @carbon/react The global styles in app/globals.scss were customized with this code snippet: @use '@carbon/reac ...

Unable to test the subscribe functionality in Angular

There is a subscribe method in my ts file within ngAfterViewInit() that is not triggering as expected during testing and debugging. I need to manually set mock data inside the subscribe method for testing purposes. ts file import mockData from 'test ...

AbstractControl is missing the 'controls' property in Angular4

Many blogs have discussed this error, but none specifically for angular4. I am dynamically adding and removing controls on the form. Add controls to the form during initialization ngOnInit() { this.lienHolder = this._fb.group({ ...

There is a Typescript error stating that the argument of type 'NodeListOf<HTMLInputElement> | undefined' cannot be assigned to the parameter of type 'Iterable<HTMLInputElement> ...'

While working on my React/Typescript App, I encountered an issue when trying to access an array of inputs in an event listener using 'e.currentTarget'. To solve this, I utilized Array.from() to convert the NodeListOf into an array and ensured tha ...