I am trying to integrate the angular-calendar context menu from here..
https://mattlewis92.github.io/angular-calendar/#/context-menu on of the child module called Calendar integrates it.
after installing all necessary module, the context-menu not working for me.
here is my child module :
import { NgModule } from '#angular/core';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { HttpClientModule } from "#angular/common/http";
import { CalendarModule, DateAdapter } from 'angular-calendar';
import { ContextMenuModule } from 'ngx-contextmenu';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { StoreModule } from '#ngrx/store';
import { EffectsModule } from '#ngrx/effects';
import { reducerCalendar } from "./state/calendar.reducer";
import { EffectsEvents } from "./state/calendar.effects";
import { IboCalendarComponent } from './components/ibo-calendar/ibo-calendar.component';
import { IboCalendarHeaderComponent } from './ibo-calendar-header/ibo-calendar-header.component';
import { CalendarShellComponent } from './containers/calendar-shell/calendar-shell.component';
import { SharedModule } from "./../shared-components/shared.module";
const iboCalenderRoutes: Routes = [
// { path: '', redirectTo:'setupConfig', pathMatch:'full' },
{ path: 'iboCalendar', component: CalendarShellComponent }
];
#NgModule({
declarations: [IboCalendarComponent, IboCalendarHeaderComponent, CalendarShellComponent],
imports: [
CommonModule,
BrowserAnimationsModule,
HttpClientModule,
SharedModule,
CalendarModule.forRoot({
provide: DateAdapter,
useFactory: adapterFactory
}),
ContextMenuModule.forRoot({
useBootstrap4: true
}),
RouterModule.forChild(iboCalenderRoutes),
EffectsModule.forFeature([EffectsEvents]),
StoreModule.forFeature('reducerCalendar', reducerCalendar)
],
exports: [ ]
})
export class iboCalendarModule { }
here is the ts file :
import { Component, OnInit, ChangeDetectionStrategy, Input, OnChanges } from '#angular/core';
import { CalendarService } from "./../../services/calendar.service";
import { ModelEvent, EventState } from "./../../models/model.event";
import { CalendarEvent } from 'angular-calendar';
import { Observable, Subject } from 'rxjs';
import { colors } from "./../../utilities/colors";
import { tap } from 'rxjs/operators';
declare var $:any;
#Component({
selector: 'ibo-calendar',
templateUrl: './ibo-calendar.component.html',
styleUrls: ['./ibo-calendar.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class IboCalendarComponent implements OnChanges,OnInit {
view: string = 'month';
// viewDate: Date = new Date('August 19, 2018');
viewDate: Date = new Date()
#Input() events:ModelEvent[];
#Input() currentEvent: ModelEvent;
refresh: Subject<any> = new Subject();
constructor() { }
ngOnInit() {
const headerHeight = $('.site-header').outerHeight();
//moving content down to header
$('body').css({paddingTop: headerHeight});
}
ngOnChanges() {
if( this.currentEvent ) {
this.viewDate = new Date(this.currentEvent.start);
}
}
eventClicked({ event }: { event: CalendarEvent }): void {
console.log('Event clicked', event);
}
addEvent(date:Date):void {
console.log('date is', date);
this.events.push({
id : 0,
start : date,
title : 'New Event',
end : new Date(),
allDay : false
})
this.refresh.next();
}
}
here is the template file :
<div class="container-fluid site-content">
<ibo-calendar-header [(view)]="view" [(viewDate)]="viewDate"></ibo-calendar-header>
<context-menu #basicMenu>
<ng-template contextMenuItem (execute)="addEvent($event.item)">
Add event
</ng-template>
</context-menu>
<ng-template
#monthCellTemplate
let-day="day"
let-openDay="openDay"
let-locale="locale"
let-tooltipPlacement="tooltipPlacement"
let-highlightDay="highlightDay"
let-unhighlightDay="unhighlightDay"
let-eventClicked="eventClicked"
>
<div
class="fill-height"
[contextMenu]="basicMenu"
[contextMenuSubject]="day.date"
>
<div class="cal-cell-top">
<span class="cal-day-badge" *ngIf="day.badgeTotal > 0"
>{{ day.badgeTotal }}</span
>
<span class="cal-day-number"
>{{ day.date | calendarDate:'monthViewDayNumber':locale }}</span
>
</div>
<div class="cal-events">
<div
class="cal-event"
*ngFor="let event of day.events"
[style.backgroundColor]="event.color.primary"
[ngClass]="event?.cssClass"
(mouseenter)="highlightDay.emit({event: event})"
(mouseleave)="unhighlightDay.emit({event: event})"
[mwlCalendarTooltip]="event.title | calendarEventTitle:'monthTooltip':event"
[tooltipPlacement]="tooltipPlacement"
(click)="$event.stopPropagation(); eventClicked.emit({event: event})"
></div>
</div>
</div>
</ng-template>
<ng-template
#weekHeaderTemplate
let-days="days"
let-locale="locale"
let-dayHeaderClicked="dayHeaderClicked"
>
<div class="cal-day-headers">
<div
class="cal-header"
*ngFor="let day of days"
[class.cal-past]="day.isPast"
[class.cal-today]="day.isToday"
[class.cal-future]="day.isFuture"
[class.cal-weekend]="day.isWeekend"
(click)="dayHeaderClicked.emit({day: day})"
[contextMenu]="basicMenu"
[contextMenuSubject]="day.date"
>
<b>{{ day.date | calendarDate:'weekViewColumnHeader':locale }}</b><br />
<span
>{{ day.date | calendarDate:'weekViewColumnSubHeader':locale }}</span
>
</div>
</div>
</ng-template>
<ng-template #dayHourSegmentTemplate let-segment="segment" let-locale="locale">
<div
class="cal-hour-segment"
[ngClass]="segment.cssClass"
[contextMenu]="basicMenu"
[contextMenuSubject]="segment.date"
>
<div [hidden]="!segment.isStart" class="cal-time">
{{ segment.date | calendarDate:'dayViewHour':locale }}
</div>
</div>
</ng-template>
<div class="alert alert-info">
Click on a day on the view.
<strong *ngIf="clickedDate">You clicked on this day: {{ clickedDate | date:'medium' }}</strong>
</div>
<div>
<div [ngSwitch]="view">
<mwl-calendar-month-view *ngSwitchCase="'month'" [viewDate]="viewDate"
[events]="events" (eventClicked)="eventClicked($event)" (dayClicked)="clickedDate = $event.day.date">
</mwl-calendar-month-view>
<mwl-calendar-week-view *ngSwitchCase="'week'"
[viewDate]="viewDate" [events]="events" (eventClicked)="eventClicked($event)" (dayHeaderClicked)="clickedDate = $event.day.date">
</mwl-calendar-week-view>
<mwl-calendar-day-view *ngSwitchCase="'day'"
[viewDate]="viewDate" [events]="events" (eventClicked)="eventClicked($event)">
</mwl-calendar-day-view>
</div>
</div>
</div>
Getting no errors as well.
any one guide me? thanks in advance.
Related
Here is my createFeatureSelector ts file :
import { State } from "./../../state/app.state";
import { EventState, ModelEvent } from "./../models/model.event";
import { createFeatureSelector, createSelector, ActionReducerMap } from "#ngrx/store";
export interface NewState extends State {
events:EventState
}
const getCalendarFeatureState = createFeatureSelector<EventState>("reducer");
export const getEvents = createSelector(getCalendarFeatureState, state => state.events );
my events shell component ( where i call the getEvents ):
import { Component, OnInit, ChangeDetectionStrategy } from '#angular/core';
import { Store, select } from '#ngrx/store';
import { Observable } from 'rxjs';
import * as fromRoot from "./../../state";
import { CalendarActions, Load } from "./../../state/calendar.actions";
import { ModelEvent, EventState } from "./../../models/model.event";
#Component({
selector: 'calendar-shell',
templateUrl: './calendar-shell.component.html',
changeDetection:ChangeDetectionStrategy.OnPush
})
export class CalendarShellComponent implements OnInit {
events$:Observable<any>
constructor(private store:Store<fromRoot.NewState>) { }
ngOnInit():void{
this.store.dispatch(new Load());
this.events$ = this.store.pipe(select(fromRoot.getEvents)); //getting nothing!!
}
}
template :
<div *ngIf="events$ | async"> //shows nothing!!
<ul>
<li *ngFor="let item of events">{{item.title}}</li>
</ul>
</div>
Any help? thanks in advance. ( ready to provide further details if any )
I update the dom element like this:
<div *ngIf="events$ | async"> //shows nothing!!
<ul>
<li *ngFor="let item of events | async">{{item.title}}</li>
</ul>
</div>
works fine.
I'm new to Angular and I'm having a problem with map data from my Rails app to the Angular app. I know I need to do some customisation to the code, but I don't really know how.
I want to mention that I'm using Rails 5.2 and Active Model Serializer for the json request.
In my rails app I have Course,Segment,Quiz,Video models and the relations are:
Course had many Segments
Segments can be Quiz or Video and I use STI so the quizzes and videos
are in segments table
This is the json file I get from the rails app and I want to map:
[
{
"id":1,
"title":"Introduction",
"author":"Dana Inbar",
"segments":[
{
"id":1,
"name":"Intro01",
"data":"http://www.video.com/1/1"
},
{
"id":2,
"name":"Intro02",
"data":"http://www.video.com/1/2"
},
{
"id":3,
"name":"Intro03",
"data":"[
{
"question 1" : "___",
"answers" : {
"1" : "____",
"2" : "____",
"3" : "____"
},
"correct_answer" : "2"
},
]"
}
]
},
{
"id":2,
"title":"Master the ELN",
"author":"Dana Inbar",
"segments":[
]
},
{
"id":3,
"title":"Master the Inventory",
"author":"Dana Inbar",
"segments":[
]
}
]
This are my angular files:
app.module
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { RouterModule, Routes } from '#angular/router';
import { FormsModule } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CourseModule } from './courses/course.module';
import { CourseService } from './courses/course.service';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
CourseModule,
FormsModule
],
providers: [CourseService],
bootstrap: [AppComponent]
})
export class AppModule { }
courses/course
export interface IQuiz {}
export interface IVideo {}
export interface ISegment {
segment_id: string;
name: string;
type: string;
data: string;
}
export interface ICourse {
course_id: number;
title: string;
autor: string;
segments: {
[segment_id: string]: ISegment,
[name: string]: ISegment,
[type: string]: ISegment,
[data: string]: ISegment
}
}
courses/course.service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map, tap, catchError } from 'rxjs/operators';
import { ICourse } from './course';
// Inject Data from Rails app to Angular app
#Injectable()
export class CourseService{
private courseUrl = 'http://localhost:3000/courses.json';
constructor(private http: HttpClient) { }
// Get Courses from Rails API App
getCourses(): Observable<ICourse[]> {
return this.http.get<ICourse[]>(this.courseUrl)
.map((res: Response) => res.json()data)
.catch(this.handleError);
}
// Handle Any Kind of Errors
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server Error');
}
}
courses/course.module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { MatSidenavModule } from '#angular/material/sidenav';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { CourseListComponent } from './course-list/course-list.component';
import { CourseDetailComponent } from './course-detail/course-detail.component';
import { CourseService } from './course.service';
import { CoursePlayComponent } from './course-play/course-play.component';
const coursesRoutes: Routes = [
{ path: 'courses', component: CourseListComponent },
{ path: 'courses/:id', component: CourseDetailComponent },
{ path: 'courses/:id/1', component: CoursePlayComponent }
]
#NgModule({
imports: [
CommonModule,
MatSidenavModule,
BrowserAnimationsModule,
RouterModule.forChild(
coursesRoutes
)
],
declarations: [
CourseListComponent,
CourseDetailComponent,
CoursePlayComponent
],
providers: [
CourseService
]
})
export class CourseModule { }
courses/course-list/course-list.component
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { ICourse } from '../course';
import { CourseService } from '../course.service';
#Component({
selector: 'lg-course-list',
templateUrl: './course-list.component.html',
styleUrls: ['./course-list.component.sass']
})
export class CourseListComponent implements OnInit {
pageTitle = "LabGuru Academy";
courses: ICourse[] =[];
errorMessage: string;
constructor(private courseService: CourseService) { }
ngOnInit() {
this.courseService.getCourses()
.subscribe(
courses => this.courses = courses,
errorMessage => this.errorMessage = <any>error
);
}
}
courses/course-list/course-list.html
<div class="row mt-3 no-gutters">
<div class="col-lg-8">
<img src="./assets/images/lg-purple.png" class="d-inline-block align-top" alt="">
</div>
</div>
<div class="jumbotron">
<div class="container text-center">
<h1>{{pageTitle}}</h1>
</div>
</div>
<div class="container-fluid bg-3 text-center">
<div class="row justify-content-lg-center">
<div class="col-sm-3" *ngFor="let course of courses | async">
<div class="card">
<div class="card-body">
<h3 class="card-title">{{course.title}}</h3>
<p class="card-text"><small class="text-muted">6 Lessons</small></p>
</div>
</div>
</div>
</div>
</div>
<br><br>
courses/course-list/course-list.sass
$pos: 70px
$color: #5c0099
$bg-col: #FFFFFF
$hig: 15rem
$wid: 15rem
$left: 5%
$top: 30%
$right: 7%
.jumbotron
background-color: transparent
color: $color
.col-sm-3
position: relative
min-height: 1px
padding-left: $left
outline-offset: none
.card
border-color: $color
background-color: $bg-col
width: $wid
height: $hig
.card-title
position: absolute
text-align: center
padding: inherit
.card-text
position: absolute
bottom: $left
right: $right
<div class="example-container">
<div class="pb-16" fxLayout="row" fxLayoutAlign="start center">
<div class="h2 secondary-text">
<b>
<u>Profile Details of {{rows ? rows?.categoryName : ''}}</u>
</b>
</div>
</div>
<br />
<mat-form-field>
<mat-label>Category Name</mat-label>
<input matInput placeholder="category name" value="{{rows ? rows?.categoryName : ''}}">
</mat-form-field>
<br />
<br />
<mat-form-field class="example-full-width">
<mat-label>Category Description</mat-label>
<textarea matInput placeholder="category description" value="{{rows ? rows?.categoryDesc : ''}}"></textarea>
</mat-form-field>
</div>
This is component.html
import { Component,OnInit,Input } from "#angular/core";
import { MatSnackBar } from '#angular/material';
import { coerceBooleanProperty } from "#angular/cdk/coercion";
import { HttpClient } from "#angular/common/http";
import { ActivatedRoute } from "#angular/router";
import { FormBuilder, FormGroup, Validators,FormControl } from
'#angular/forms';
import { Location} from '#angular/common';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/delay';
import 'rxjs/add/operator/map';
import {ServiceContactsFakeDb} from '../../../../../fuse-fake-db/service-
contacts';
import { Data } from '../../../../../fuse-fake-db/hero';
import { LIST } from '../../../../../fuse-fake-db/mock-heroes';
import {CategoryService} from "../category.service";
#Component({
selector: 'profile-detail',
templateUrl: './profile.component.html',
styleUrls:['./component.scss'],
providers:[CategoryService]
})
export class ProfileComponent implements OnInit {
constructor (private location:Location,private http: HttpClient,private
service:CategoryService,private _Activatedroute:ActivatedRoute){
}
name = new FormControl('', [Validators.required]);
name1 = new FormControl('', [Validators.required]);
favoriteSeason: any;
_card = false;
profiles = LIST;
#Input() category;
selectedProfile: Data;
rawdata:any[];
rows: any[];
reorderable = true;
categoryName : any[];
categoryDesc : any = {};
data = [];
item:string[];
id:string;
catName: string;
catDesc: string;
//selectedProfile: ServiceContactsFakeDb;
setDataLayoutType(value: boolean) {
this._card = coerceBooleanProperty(value);
}
ngOnInit(){
// this.getDetail();
this.id=this._Activatedroute.snapshot.params['id'];
console.log(this.id);
this.service.getcategory().subscribe(res => {
this.rawdata = res;
for(var i=0;i<this.rawdata.length;i++){
if(this.id == this.rawdata[i].id){
this.rows=this.rawdata[i];
console.log(this.rows);
}
}
});
}
In this code I am getting error in component.html file like this :
[Angular] Identifier 'categoryName' is not defined. 'Array' does not contain such a member .
I am fetching the values from an api, I am getting the output but still it shows errors in this line "value="{{rows ? rows?.categoryName : ''}}"
I had defined rows as a array replace it with rows: any={} instead of rows: any[];
import { Component, Input } from "#angular/core";
import "./loadingSpinner.component.css!";
#Component({
selector: "loading-spinner-Parent",
template: `
<div *ngIf="showSpinner" class="loader-directive-wrapper">
<div class="loader"></div>
</div>`
})
export class LoadingSpinnerComponent {
#Input() public showSpinner: boolean = false;
}
I am building a site for upcoming concert events. When I create a new event I got it to save to the backend (Ruby on Rails) and immediately display the new event in the event list. However, when I delete an event, the event gets deleted in the database but the front end does not refresh.
event-create.component.ts
import { Component, OnDestroy, OnInit } from '#angular/core';
import { FormControl, FormGroup, Validators, FormBuilder } from "#angular/forms";
import { EventService } from "../event.service";
import { Event } from "../event";
import { Venue } from "../../venue/venue";
import { VenueService } from "../../venue/venue.service";
import { ActivatedRoute, Router} from '#angular/router';
import { BsDatepickerConfig } from 'ngx-bootstrap/datepicker'
import { DataService } from '../../data.service';
#Component({
selector: 'app-event-create',
templateUrl: './event-create.component.html',
styleUrls: ['./event-create.component.scss']
})
export class EventCreateComponent implements OnInit {
id: number;
event: Event;
venues: Venue[];
bsValue: Date = new Date();
date: string;
time: string;
datepickerModel: Date = new Date();
bsConfig: Partial<BsDatepickerConfig>;
eventTime: Date = new Date(this.bsValue.getFullYear(), this.bsValue.getMonth(), this.bsValue.getDay(), 19, 0, 0, 0);
mstep: number = 15;
eventForm: FormGroup;
constructor(private route: ActivatedRoute,
private router: Router,
private eventService: EventService,
private venueService: VenueService,
private data: DataService,
fb: FormBuilder) {
this.eventForm = fb.group({
'title': [null, Validators.required],
'venue': [1, Validators.required],
'date': null,
'time': null,
'description': [null, Validators.required]
});
this.bsConfig = Object.assign({}, { containerClass: 'theme-red' });
}
ngOnInit(): void {
this.getVenues();
}
getVenues(){
this.venueService.query().subscribe(
venues => {
this.venues = venues;
},
err => {
console.log(err);
}
);
}
onSubmit() {
Object.keys(this.eventForm.controls).forEach(field => {
const control = this.eventForm.get(field);
control.markAsTouched({ onlySelf: true });
});
if (this.eventForm.valid) {
let date: Date = new Date(this.eventForm.controls['date'].value);
let time: Date = new Date(this.eventForm.controls['time'].value);
let event: Event = new Event(
null,
this.eventForm.controls['venue'].value,
this.formatTimestamp(date, time),
this.eventForm.controls['title'].value,
this.eventForm.controls['description'].value
);
this.eventService.save(event).subscribe();
this.data.addEvent(event);
this.router.navigate(['/event']);
}
}
formatTimestamp(date: Date, time: Date): number {
let timezoneOffset: number = time.getTimezoneOffset() / 60;
if((time.getHours() + timezoneOffset) > 23){
date.setDate(date.getDate() + 1);
}
date.setUTCHours(time.getUTCHours());
date.setUTCMinutes(time.getMinutes());
date.setUTCSeconds(time.getSeconds());
return date.getTime();
}
redirectUserPage() {
this.router.navigate(['/user']);
}
}
event-index.component.ts
import { Component, OnInit } from '#angular/core';
import { Event } from '../event';
import { EventService } from '../event.service';
import { Router } from '#angular/router';
import { DataService } from '../../data.service';
import { Output, EventEmitter } from '#angular/core';
#Component({
selector: 'app-event-index',
templateUrl: './event-index.component.html',
styleUrls: ['./event-index.component.scss']
})
export class EventIndexComponent implements OnInit {
#Output()
someEvent = new EventEmitter();
event: Event;
private events: Event[];
constructor(
private router: Router,
private eventService: EventService,
private data: DataService
) { }
ngOnInit() {
this.getEvents();
this.data.currentEvent.subscribe(event => this.event = event);
}
getEvents(){
this.eventService.query().subscribe(
events => {
this.events = events;
},
err => {
console.log(err);
}
)
}
newEvent(){
this.router.navigate(['/event/create']);
}
editEvent(event: Event){
if(event){
this.router.navigate(['/event/edit', event]);
}
}
deleteEvent(event: Event){
let index = this.events.indexOf(event);
if(index > -1){
this.eventService.delete(event).subscribe(
event => {
this.events.slice(index, 1);
}
);
}
}
}
data.service.ts
import { Injectable } from '#angular/core';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Event } from './event/event';
#Injectable()
export class DataService{
currentEvent: BehaviorSubject<Event> = new BehaviorSubject<Event>(null);
public addEvent(newEvent: Event): void{
this.currentEvent.next(newEvent);
}
}
event-create.component.html
<div class="row justify-content-center">
<h1>New Event</h1>
</div>
<div class='row justify-content-center'>
<div class='col-6'>
<form [formGroup]='eventForm' (ngSubmit)="onSubmit(eventForm.value)">
<div class='form-group'>
<label>Title</label>
<input type="text" class='form-control' [ngClass]="{'is-invalid': eventForm.controls['title'].invalid && eventForm.controls['title'].touched}" formControlName="title">
<div *ngIf="eventForm.controls['title'].hasError('required')" class="invalid-feedback">Title is required</div>
</div>
<div class='form-group'>
<label>Description</label>
<textarea formControlName="description" class='form-control' [ngClass]="{'is-invalid': eventForm.controls['description'].invalid && eventForm.controls['description'].touched}"></textarea>
<div *ngIf="eventForm.controls['description'].hasError('required')" class="invalid-feedback">Description is required</div>
</div>
<div class='form-group'>
<label>Venue</label>
<select class='form-control' formControlName='venue'>
<option *ngFor="let venue of venues" [value]="venue.id">{{venue.name}}</option>
</select>
</div>
<div class="form-group">
<label>Date</label>
<input type="text" class="form-control" bsDatepicker [bsConfig]="bsConfig" [(ngModel)]="datepickerModel" formControlName='date'>
</div>
<div class='form-group'>
<label>Time</label>
<timepicker [(ngModel)]="eventTime" [minuteStep]="mstep" formControlName='time'></timepicker>
</div>
<button type="submit" class='btn btn-default'>Submit</button>
<pre>{{eventForm.value | json}}</pre>
</form>
</div>
</div>
event.service.ts
import { Injectable } from '#angular/core';
import { Event } from './event';
import { HttpClient } from '#angular/common/http';
import { Response } from '#angular/http';
import { Observable } from 'rxjs/Observable'
#Injectable()
export class EventService {
private apiUrl = 'http://localhost:3000/events';
constructor(private http: HttpClient) {}
query(): Observable<any>{
return this.http.get(this.apiUrl);
}
get(id: number): Observable<Event>{
return null;
}
save(event: Event): Observable<any>{
return this.http.post(this.apiUrl, event);
}
delete(event: Event): Observable<any>{
console.log(event);
return this.http.delete(this.apiUrl + '/' + event.id)
}
update(event: Event): Observable<Event>{
return null;
}
}
You are using slice() where you should be using splice() in deleteEvent()
Try changing:
this.events.slice(index, 1);
To
this.events.splice(index, 1);