2

I seem to have a problem I can't solve.

I want 'dialogTitle' variable to also display the startHour and startMinute variables alongside the title variable. However, I seem to get the title and 'undefined' twice after the title. What should I do?

event-form.component.ts

import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';

import { MatColors } from '@fuse/mat-colors';

import { CalendarEvent } from 'angular-calendar';
import { CalendarEventModel } from '../event.model';

import { locale as eventFormEnglish } from './i18n/en';
import { locale as eventFormDutch } from './i18n/nl';

import { FuseCalendarComponent } from '../calendar.component';

@Component({
    selector     : 'fuse-calendar-event-form-dialog',
    templateUrl  : './event-form.component.html',
    styleUrls    : ['./event-form.component.scss'],
    encapsulation: ViewEncapsulation.None
})

export class FuseCalendarEventFormDialogComponent
{
    event: CalendarEvent;
    dialogTitle: string;
    eventForm: FormGroup;
    action: string;
    startHour: string;
    startMinute: string;
    endHour: string;
    endMinute: string;
    presetColors = MatColors.presets;

    //Shows dropdown items

    startTimeHours = [
        {value: 'time-0', viewValue: '7'},
        {value: 'time-1', viewValue: '8'},
        {value: 'time-2', viewValue: '9'},
        {value: 'time-3', viewValue: '10'},
        {value: 'time-4', viewValue: '11'},
        {value: 'time-5', viewValue: '12'},
        {value: 'time-6', viewValue: '13'},
        {value: 'time-7', viewValue: '14'},
        {value: 'time-8', viewValue: '15'},
        {value: 'time-9', viewValue: '16'},
        {value: 'time-10', viewValue: '17'},
        {value: 'time-11', viewValue: '18'},
        {value: 'time-12', viewValue: '19'},
        {value: 'time-13', viewValue: '20'},
        {value: 'time-14', viewValue: '21'},
        {value: 'time-15', viewValue: '22'},
        {value: 'time-16', viewValue: '23'}
    ];
    startTimeMinutes = [
        {value: 'time-0', viewValue: '0'},
        {value: 'time-1', viewValue: '5'},
        {value: 'time-2', viewValue: '10'},
        {value: 'time-3', viewValue: '15'},
        {value: 'time-4', viewValue: '20'},
        {value: 'time-5', viewValue: '25'},
        {value: 'time-6', viewValue: '30'},
        {value: 'time-7', viewValue: '35'},
        {value: 'time-8', viewValue: '40'},
        {value: 'time-9', viewValue: '45'},
        {value: 'time-10', viewValue: '50'},
        {value: 'time-11', viewValue: '55'}
    ];

    endTimeHours = [
        {value: 'time-0', viewValue: '7'},
        {value: 'time-1', viewValue: '8'},
        {value: 'time-2', viewValue: '9'},
        {value: 'time-3', viewValue: '10'},
        {value: 'time-4', viewValue: '11'},
        {value: 'time-5', viewValue: '12'},
        {value: 'time-6', viewValue: '13'},
        {value: 'time-7', viewValue: '14'},
        {value: 'time-8', viewValue: '15'},
        {value: 'time-9', viewValue: '16'},
        {value: 'time-10', viewValue: '17'},
        {value: 'time-11', viewValue: '18'},
        {value: 'time-12', viewValue: '19'},
        {value: 'time-13', viewValue: '20'},
        {value: 'time-14', viewValue: '21'},
        {value: 'time-15', viewValue: '22'},
        {value: 'time-16', viewValue: '23'}
    ];
    endTimeMinutes = [
        {value: 'time-0', viewValue: '0'},
        {value: 'time-1', viewValue: '5'},
        {value: 'time-2', viewValue: '10'},
        {value: 'time-3', viewValue: '15'},
        {value: 'time-4', viewValue: '20'},
        {value: 'time-5', viewValue: '25'},
        {value: 'time-6', viewValue: '30'},
        {value: 'time-7', viewValue: '35'},
        {value: 'time-8', viewValue: '40'},
        {value: 'time-9', viewValue: '45'},
        {value: 'time-10', viewValue: '50'},
        {value: 'time-11', viewValue: '55'}
    ];

    constructor(
        public dialogRef: MatDialogRef<FuseCalendarEventFormDialogComponent>,
        @Inject(MAT_DIALOG_DATA) private data: any,
        private formBuilder: FormBuilder
    )
    {
        this.event = data.event;
        this.action = data.action;

        if ( this.action === 'edit' )
        {
            this.dialogTitle = this.event.title + " - " + this.startHour + ":" + this.startMinute;
        }
        else
        {
            this.dialogTitle = 'New Event';
            this.event = new CalendarEventModel({
                start: data.date,
                end  : data.date
            });
        }

        this.eventForm = this.createEventForm();
    }

    createEventForm()
    {
        return new FormGroup({
            title       : new FormControl(this.event.title),
            start       : new FormControl(this.event.start),
            end         : new FormControl(this.event.end),
            startHour   : new FormControl(this.startHour),
            startMinute : new FormControl(this.startMinute),
            endHour     : new FormControl(this.endHour),
            endMinute   : new FormControl(this.endMinute),
            allDay      : new FormControl(this.event.allDay),
            color       : this.formBuilder.group({
                primary     : new FormControl(this.event.color.primary),
                secondary   : new FormControl(this.event.color.secondary)
            }),
            meta        :
                this.formBuilder.group({
                    location: new FormControl(this.event.meta.location),
                    notes   : new FormControl(this.event.meta.notes)
                })
        });
    }
}

event-form.component.html

<div class="dialog-content-wrapper">
    <mat-toolbar matDialogTitle class="mat-accent m-0">
        <div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
            <span class="title dialog-title">{{dialogTitle}}</span>
            <button mat-button class="mat-icon-button"
                    (click)="dialogRef.close()"
                    aria-label="Close dialog">
                <mat-icon>close</mat-icon>
            </button>
        </div>
    </mat-toolbar>

    <div mat-dialog-content class="p-24 m-0" fusePerfectScrollbar>

        <form name="eventForm" [formGroup]="eventForm" class="event-form w-100-p" fxLayout="column" fxFlex>

            <mat-form-field class="w-100-p">
                <input matInput
                       name="title"
                       formControlName="title"
                       [placeholder]="'FORM.TITLE' | translate"
                       required>
            </mat-form-field>

            <div class="py-16" fxFlex="1 0 auto" fxLayout="row">
                <mat-slide-toggle
                    name="allDay"
                    formControlName="allDay"
                    class="mr-24"
                    aria-label="All day">
                    {{ 'FORM.ALLDAY' | translate }}
                </mat-slide-toggle>
            </div>

            <div class="py-16" fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row" formGroupName="color">

                <mat-form-field class="mr-sm-24" fxFlex>
                    <input matInput
                           class="primary-color-input"
                           name="primary color"
                           formControlName="primary"
                           [placeholder]="'FORM.PRIMARYCOLOR' | translate"
                           [(colorPicker)]="event.color.primary"
                           cpWidth="290px"
                           [cpPresetColors]="presetColors"
                           [style.background]="event.color.primary"
                           (colorPickerChange)="event.color.primary = $event; eventForm.patchValue({color:{primary:$event}})"/>
                </mat-form-field>

                <mat-form-field fxFlex>
                    <input matInput
                           class="secondary-color-input"
                           name="secondary color"
                           formControlName="secondary"
                           [placeholder]="'FORM.SECONDARYCOLOR' | translate"
                           [(colorPicker)]="event.color.secondary"
                           cpWidth="290px"
                           [cpPresetColors]="presetColors"
                           [style.background]="event.color.secondary"
                           (colorPickerChange)="event.color.secondary = $event; eventForm.patchValue({color:{secondary:$event}})"/>
                </mat-form-field>

            </div>

            <div fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row">

                <mat-form-field class="mr-sm-24" fxFlex>
                    <input matInput [matDatepicker]="startDatePicker" [placeholder]="'FORM.STARTDATE' | translate"
                           name="start"
                           formControlName="start" required>
                    <mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle>
                    <mat-datepicker #startDatePicker></mat-datepicker>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.STARTHOUR' | translate" formControlName="startHour" required>
                        <mat-option *ngFor="let startTimeHour of startTimeHours" [value]="startTimeHour">
                          {{startTimeHour.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.STARTMINUTE' | translate" formControlName="startMinute" required>
                        <mat-option *ngFor="let startTimeMinute of startTimeMinutes" [value]="startTimeMinute">
                          {{startTimeMinute.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

            </div>

            <div fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row">

                <mat-form-field class="mr-sm-24" fxFlex>
                    <input matInput [matDatepicker]="endDatePicker" [placeholder]="'FORM.ENDDATE' | translate"
                           name="end"
                           formControlName="end" required>
                    <mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle>
                    <mat-datepicker #endDatePicker></mat-datepicker>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.ENDHOUR' | translate" formControlName="endHour" required>
                        <mat-option *ngFor="let endTimeHour of endTimeHours" [value]="endTimeHour">
                          {{endTimeHour.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.ENDMINUTE' | translate" formControlName="endMinute" required>
                        <mat-option *ngFor="let endTimeMinute of endTimeMinutes" [value]="endTimeMinute">
                          {{endTimeMinute.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

            </div>

            <mat-form-field formGroupName="meta" class="w-100-p">
                <input matInput
                       name="location"
                       formControlName="location"
                       [placeholder]="'FORM.LOCATION' | translate">
            </mat-form-field>

            <mat-form-field formGroupName="meta" class="w-100-p">

                <textarea matInput
                          formControlName="notes"
                          [placeholder]="'FORM.NOTES' | translate"
                          mat-maxlength="250"
                          max-rows="4">
                </textarea>
            </mat-form-field>

        </form>

    </div>

    <div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">

        <button *ngIf="action !=='edit'"
                mat-raised-button
                (click)="dialogRef.close(eventForm)"
                class="save-button mat-accent"
                [disabled]="eventForm.invalid"
                aria-label="SAVE">
            SAVE
        </button>

        <button *ngIf="action ==='edit'"
                mat-raised-button
                (click)="dialogRef.close(['save',eventForm])"
                class="save-button mat-accent"
                [disabled]="eventForm.invalid"
                aria-label="SAVE">
             {{ 'FORM.SAVE' | translate }}
        </button>

        <button *ngIf="action ==='edit'"
                mat-button
                class="mat-icon-button"
                (click)="dialogRef.close(['delete',eventForm])"
                aria-label="Delete"
                matTooltip="Delete">
            <mat-icon>delete</mat-icon>
        </button>
    </div>
</div>

I believe it has to do with the fact I haven't declared the two variables the right way or something like that, but I'm kinda new, so I'm not sure what I'm doing wrong here. Is it the order?

EDIT: It should get the startHour and startMinute variables from the database entries, but I do not know how. The database is declared in another file:

calendar.component.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Subject } from 'rxjs/Subject';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';

import { MatDialog, MatDialogRef } from '@angular/material';
import { startOfDay, isSameDay, isSameMonth } from 'date-fns';

import { CalendarEvent, CalendarEventAction, CalendarEventTimesChangedEvent, CalendarMonthViewDay } from 'angular-calendar';

import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
import { fuseAnimations } from '@fuse/animations';

import { FuseCalendarEventFormDialogComponent } from './event-form/event-form.component';
import { CalendarEventModel } from './event.model';

import 'rxjs/add/operator/map';

export interface Ride { allDay: boolean; color: Object; primary: string; secondary: string; end: string; meta: Object; location: string; notes: string; start: string; title: string; }
export interface RideId extends Ride { id: string }

@Component({
    selector     : 'fuse-calendar',
    templateUrl  : './calendar.component.html',
    styleUrls    : ['./calendar.component.scss'],
    encapsulation: ViewEncapsulation.None,
    animations   : fuseAnimations
})
export class FuseCalendarComponent implements OnInit
{   
    view: string;
    viewDate: Date;
    events: CalendarEvent[];
    locale: string = 'nl';
    public actions: CalendarEventAction[];
    activeDayIsOpen: boolean;
    refresh: Subject<any> = new Subject();
    dialogRef: any;
    confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
    selectedDay: any;
    rides: Observable<RideId[]>;
    ride: Observable<Ride>;

    private ridesCollection: AngularFirestoreCollection<Ride>;
    private ridesDocument: AngularFirestoreDocument<Ride>;

    vehicle = [
        {value: 'vehicle-0', viewValue: 'Test 1'},
        {value: 'vehicle-1', viewValue: 'Test 2'}
    ]

    constructor(
        public dialog: MatDialog,
        private readonly db: AngularFirestore,
    )
    {
        this.view = 'month';
        this.viewDate = new Date();
        this.activeDayIsOpen = true;
        this.selectedDay = {date: startOfDay(new Date())};

        this.actions = [
            {
                label  : '<i class="material-icons s-16">edit</i>',
                onClick: ({event}: { event: CalendarEvent }): void => {
                    this.editEvent('edit', event);
                }
            },
            {
                label  : '<i class="material-icons s-16">delete</i>',
                onClick: ({event}: { event: CalendarEvent }): void => {
                    this.deleteEvent(event);
                }
            }
        ];

        /**
         * Get events from service/server
         */
         this.ridesCollection = db.collection<Ride>('rides');

         this.rides = this.ridesCollection.snapshotChanges().map(actions => {
            return actions.map(a => {
            const data = a.payload.doc.data() as Ride;
            const id = a.payload.doc.id;
            return { id, ...data };
      });
    });

//        this.setEvents();
    }

    ngOnInit()
    {
        /**
         * Watch re-render-refresh for updating db
         */
//        this.refresh.subscribe(updateDB => {
//            // console.warn('REFRESH');
//            if ( updateDB )
//            {
//                // console.warn('UPDATE DB');
//                this.calendarService.updateEvents(this.events);
//            }
//        });

//        this.calendarService.onEventsUpdated.subscribe(events => {
//            this.setEvents();
//            this.refresh.next();
//        });

//        this.ridesDocument = this.db.doc('rides/id');
//        this.ride = this.ridesDocument.valueChanges();
    }

    setEvents()
    {
        //set this.events
//        this.events = this.ridesCollection.add(rides);
    }

    /**
     * Before View Renderer
     * @param {any} header
     * @param {any} body
     */
    beforeMonthViewRender({header, body})
    {
        // console.info('beforeMonthViewRender');
        /**
         * Get the selected day
         */
        const _selectedDay = body.find((_day) => {
            return _day.date.getTime() === this.selectedDay.date.getTime();
        });

        if ( _selectedDay )
        {
            /**
             * Set selectedday style
             * @type {string}
             */
            _selectedDay.cssClass = 'mat-elevation-z3';
        }

    }

    /**
     * Day clicked
     * @param {MonthViewDay} day
     */
    dayClicked(day: CalendarMonthViewDay): void
    {
        const date: Date = day.date;
        const events: CalendarEvent[] = day.events;

        if ( isSameMonth(date, this.viewDate) )
        {
            if ( (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) || events.length === 0 )
            {
                this.activeDayIsOpen = false;
            }
            else
            {
                this.activeDayIsOpen = true;
                this.viewDate = date;
            }
        }
        this.selectedDay = day;
        this.refresh.next();
    }

    /**
     * Event times changed
     * Event dropped or resized
     * @param {CalendarEvent} event
     * @param {Date} newStart
     * @param {Date} newEnd
     */
    eventTimesChanged({event, newStart, newEnd}: CalendarEventTimesChangedEvent): void
    {
        event.start = newStart;
        event.end = newEnd;
        // console.warn('Dropped or resized', event);
        this.refresh.next(true);
    }

    /**
     * Delete Event
     * @param event
     */
    deleteEvent(ride)
    {
        this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, {
            disableClose: false
        });

        this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete?';

        this.confirmDialogRef.afterClosed().subscribe(result => {
            if ( result )
            {
//                const eventIndex = this.events.indexOf(event);
//                this.events.splice(eventIndex, 1);
//                this.refresh.next(true);

            }
            this.confirmDialogRef = null;
        });

    }

    /**
     * Edit Event
     * @param {string} action
     * @param {CalendarEvent} event
     */
    editEvent(action: string, event: CalendarEvent)
    {
//        const eventIndex = this.events.indexOf(event);

        this.dialogRef = this.dialog.open(FuseCalendarEventFormDialogComponent, {
            panelClass: 'event-form-dialog',
            data      : {
                event : event,
                action: action
            }
        });

//        console.log(event);

        this.dialogRef.afterClosed()
            .subscribe(response => {
                if ( !response )
                {
                    return;
                }
                const actionType: string = response[0];
                const formData: FormGroup = response[1];
                switch ( actionType )
                {
                    /**
                     * Save
                     */
                    case 'save':
                        var saveData: any;
//                        this.events[eventIndex] = Object.assign(this.events[eventIndex], formData.getRawValue());
                        this.refresh.next(true);

                        saveData = formData.getRawValue();
//                        saveData.start.setHours(saveData.startHour);
//                        saveData.start.setMinutes(saveData.startMinute);

                        this.ridesDocument = this.db.doc('rides/' + event.id);
                        this.ridesDocument.set(saveData);


                        break;
                    /**
                     * Delete
                     */
                    case 'delete':

//                        this.deleteEvent(event);
                        this.ridesDocument = this.db.doc('rides/' + event.id);
                        this.ridesDocument.delete();

                        break;
                }
            });
    }

    /**
     * Add Event
     */
    addEvent(): void
    {
        this.dialogRef = this.dialog.open(FuseCalendarEventFormDialogComponent, {
            panelClass: 'event-form-dialog',
            data      : {
                action: 'new',
                date  : this.selectedDay.date
            }
        });
        this.dialogRef.afterClosed()
            .subscribe((response: FormGroup) => {
                if ( !response )
                {
                    return;
                }
                const newEvent = response.getRawValue();
//                newEvent.actions = this.actions;
//                this.events.push(newEvent);
                this.refresh.next(true);
                this.ridesCollection.add(newEvent);
            });
    }
}

Thanks in advance!

3
  • what is exactly the error(s) in the debugging console (dev tools) ? Commented Mar 29, 2018 at 11:59
  • 3
    from what i see, it seems that this.startHour and this.startMinute are declared in the class, but never given a value, so coming as undefined is not that surprising Commented Mar 29, 2018 at 12:02
  • I agree, but you see... It should pick up the startHour value from the database. That's what I want. Updated question to reflect this. Commented Mar 29, 2018 at 12:27

2 Answers 2

3

It looks like you haven't given any values to startHour or startMinute. Up where you have

startHour: string
startMinute: string

you're simply declaring that these variables are of type string, but not giving them a value. If you want to give them a value, you can either assign a value at the same point, like this:

startHour: string = 'value'
startMinute: string = 'value'

or in your constructor, right before you use them

this.event = data.event;
this.action = data.action;

this.startHour = 'value';
this.startMinute = 'value';

if ( this.action === 'edit' )
{
  this.dialogTitle = this.event.title + " - " + this.startHour + ":" + this.startMinute;
}

Hope this helped and good luck!

Sign up to request clarification or add additional context in comments.

9 Comments

It should pick up the startHour value from the database. That's what I want. I forgot to mention that, my bad... Updated question to reflect this.
From what I understand, you're getting from your data from @Inject(MAT_DIALOG_DATA) private data: any? I also see that data contains a date. If you can get the time from this, then you should able to, in your constructor, assign startHour and startMinute as such: this.startHour = data.date.hour and this.startMinute = data.date.minute, replacing hour and minute with the actual variables.
Unless I'm doing something wrong, it says it cannot read startHour when I try this.startHour = data.date.startHour.
From what I remember, Date objects have a function called getHours() and getMinutes() that you can use instead of getTime() to grab the hour and minute, respectively. So your declaration will probably look like this.startHour = data.date.getHours() and this.startMinute = data.date.getMinutes(), since date is a Date object and can use these functions.
For some reason data.date.getHours() doesn't work since it can't be read. date variable is part of the Fuse 2 library I think, but I'm not sure if it's an actual Date Object.
|
0

Declaration and Definition are 2 different things.

startHour: string; // This is just declaring a variable. We haven't defined any value for it.
console.log(this.startHour); // will give undefined.

startHour: string = '';  //This is declaring + defining the variable.
console.log(this.startHour); // will give any emppty string.

5 Comments

It should pick up the startHour value from the database. That's what I want. I forgot to mention that, my bad... Updated question to reflect this.
@WesleyOrth my advise would be to define both variables as empty string, so that they are defined while you are fetching their values from other file.
How do I fetch values from another file?
Minor note: linters would say that the second example should favor startHour = '' over having a type specified as this is already implied.
Is that more efficient? Isn't it safer to type it anyway?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.