Eroare in aplicatie Angular 6 la parsarea template-ului

angular
typescript
javascript
(Damian Florescu) #1

Salutare oameni faini!
M-am apucat de construit un Demo pentru o aplicatie in angular6 cu angularfire2 si firebase. Am dorit sa adaug in ea acest frumos calendar: https://mattlewis92.github.io/angular-calendar/#/kitchen-sink
Drept urmare dupa o serie de mici erori si mici recompletari mi-a dat terminalul code compiled succefully dar consola din browser (chrome) zice urmatoarele:

Uncaught Error: Template parse errors:
Can’t bind to ‘view’ since it isn’t a known property of ‘div’

Drept urmare daca sunt cunoscatori va pun la indemana fisierele:
app.module.ts contine:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Directive, ElementRef, Input } from '@angular/core';
import { AngularFireModule } from 'angularfire2';
import { environment } from '../environments/environment';
import { NgModel, FormsModule } from '@angular/forms';
import { DragAndDropModule } from 'angular-draggable-droppable';
import { ResizeEvent } from 'angular-resizable-element';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
// tslint:disable-next-line:max-line-length
import {MatButtonModule, MatCheckboxModule, MatToolbarModule, MatSidenavModule, MatIconModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule} from '@angular/material';
import {LayoutModule} from '@angular/cdk/layout';
import { SidenavComponent } from './sidenav/sidenav.component';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TableComponent } from './table/table.component';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { AngularFireStorageModule } from 'angularfire2/storage';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { CoreModule } from './core/core.module';
import { UserProfileComponent } from './user-profile/user-profile.component';
import { CalendarComponent } from './calendar/calendar.component';
import { ResizableModule } from 'angular-resizable-element';

@NgModule({
  declarations: [
    AppComponent,
    SidenavComponent,
    DashboardComponent,
    TableComponent,
    UserProfileComponent,
    CalendarComponent,
  ],
  imports: [
    ResizableModule,
    [DragAndDropModule.forRoot()],
    BrowserModule,
    AppRoutingModule,
    CoreModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFirestoreModule, // imports firebase/firestore, only needed for database features
    AngularFireAuthModule, // imports firebase/auth, only needed for auth features,
    AngularFireStorageModule, // imports firebase/storage only needed for storage features
    AppRoutingModule,
    [MatButtonModule, MatCheckboxModule],
    [BrowserAnimationsModule],
    LayoutModule,
    BrowserAnimationsModule,
    MatToolbarModule,
    MatButtonModule,
    MatSidenavModule,
    MatIconModule,
    MatListModule,
    MatGridListModule,
    MatCardModule,
    MatMenuModule,
    MatTableModule,
    MatPaginatorModule,
    MatSortModule,
  ],
  exports: [ RouterModule ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

calendar.component.ts contine

import {
  Component,
  ChangeDetectionStrategy,
  ViewChild,
  TemplateRef
} from '@angular/core';
import {
  startOfDay,
  endOfDay,
  subDays,
  addDays,
  endOfMonth,
  isSameDay,
  isSameMonth,
  addHours
} from 'date-fns';
import { Subject } from 'rxjs';
import {
  CalendarEvent,
  CalendarEventAction,
  CalendarEventTimesChangedEvent
} from 'angular-calendar';
import { NgbModal } from '../../../node_modules/@ng-bootstrap/ng-bootstrap';

const colors: any = {
  red: {
    primary: '#ad2121',
    secondary: '#FAE3E3'
  },
  blue: {
    primary: '#1e90ff',
    secondary: '#D1E8FF'
  },
  yellow: {
    primary: '#e3bc08',
    secondary: '#FDF1BA'
  }
};

@Component({
  selector: 'app-calendar',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['calendar.component.css'],
  templateUrl: 'calendar.component.html'
})
export class CalendarComponent {
  @ViewChild('modalContent') modalContent: TemplateRef<any>;

  view = 'month';

  viewDate: Date = new Date();

  modalData: {
    action: string;
    event: CalendarEvent;
  };

  actions: CalendarEventAction[] = [
    {
      label: '<i class="fa fa-fw fa-pencil"></i>',
      onClick: ({ event }: { event: CalendarEvent }): void => {
        this.handleEvent('Edited', event);
      }
    },
    {
      label: '<i class="fa fa-fw fa-times"></i>',
      onClick: ({ event }: { event: CalendarEvent }): void => {
        this.events = this.events.filter(iEvent => iEvent !== event);
        this.handleEvent('Deleted', event);
      }
    }
  ];

  refresh: Subject<any> = new Subject();

  events: CalendarEvent[] = [
    {
      start: subDays(startOfDay(new Date()), 1),
      end: addDays(new Date(), 1),
      title: 'A 3 day event',
      color: colors.red,
      actions: this.actions
    },
    {
      start: startOfDay(new Date()),
      title: 'An event with no end date',
      color: colors.yellow,
      actions: this.actions
    },
    {
      start: subDays(endOfMonth(new Date()), 3),
      end: addDays(endOfMonth(new Date()), 3),
      title: 'A long event that spans 2 months',
      color: colors.blue
    },
    {
      start: addHours(startOfDay(new Date()), 2),
      end: new Date(),
      title: 'A draggable and resizable event',
      color: colors.yellow,
      actions: this.actions,
      resizable: {
        beforeStart: true,
        afterEnd: true
      },
      draggable: true
    }
  ];

  activeDayIsOpen = true;

  constructor(private modal: NgbModal) {}

  dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void {
    if (isSameMonth(date, this.viewDate)) {
      this.viewDate = date;
      if (
        (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) ||
        events.length === 0
      ) {
        this.activeDayIsOpen = false;
      } else {
        this.activeDayIsOpen = true;
      }
    }
  }

  eventTimesChanged({
    event,
    newStart,
    newEnd
  }: CalendarEventTimesChangedEvent): void {
    event.start = newStart;
    event.end = newEnd;
    this.handleEvent('Dropped or resized', event);
    this.refresh.next();
  }

  handleEvent(action: string, event: CalendarEvent): void {
    this.modalData = { event, action };
    this.modal.open(this.modalContent, { size: 'lg' });
  }

  addEvent(): void {
    this.events.push({
      title: 'New event',
      start: startOfDay(new Date()),
      end: endOfDay(new Date()),
      color: colors.red,
      draggable: true,
      resizable: {
        beforeStart: true,
        afterEnd: true
      }
    });
    this.refresh.next();
  }
}

calendar.module.ts contine:

import 'flatpickr/dist/flatpickr.css';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { CalendarModule } from 'angular-calendar';
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap/modal/modal.module';
import { FlatpickrModule } from 'angularx-flatpickr';
import { CalendarComponent } from './calendar.component';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    NgbModalModule.forRoot(),
    FlatpickrModule.forRoot(),
    CalendarModule.forRoot()
  ],
  declarations: [CalendarComponent],
  exports: [CalendarComponent]
})
export class DemoModule {}

si mai e template-ul html
calendar.component.html care contine :

<ng-template #modalContent let-close="close">
  <div class="modal-header">
    <h5 class="modal-title">Event action occurred</h5>
    <button type="button" class="close" (click)="close()">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <div>
      Action:
      <pre>{{ modalData?.action }}</pre>
    </div>
    <div>
      Event:
      <pre>{{ modalData?.event | json }}</pre>
    </div>
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-outline-secondary" (click)="close()">OK</button>
  </div>
</ng-template>

<div class="row text-center">
  <div class="col-md-4">
    <div class="btn-group">
      <div
        class="btn btn-primary"
        mwlCalendarPreviousView
        [view]="view"
        [(viewDate)]="viewDate"
        (viewDateChange)="activeDayIsOpen = false">
        Previous
      </div>
      <div
        class="btn btn-outline-secondary"
        mwlCalendarToday
        [(viewDate)]="viewDate">
        Today
      </div>
      <div
        class="btn btn-primary"
        mwlCalendarNextView
        [view]="view"
        [(viewDate)]="viewDate"
        (viewDateChange)="activeDayIsOpen = false">
        Next
      </div>
    </div>
  </div>
  <div class="col-md-4">
    <h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}</h3>
  </div>
  <div class="col-md-4">
    <div class="btn-group">
      <div
        class="btn btn-primary"
        (click)="view = 'month'"
        [class.active]="view === 'month'">
        Month
      </div>
      <div
        class="btn btn-primary"
        (click)="view = 'week'"
        [class.active]="view === 'week'">
        Week
      </div>
      <div
        class="btn btn-primary"
        (click)="view = 'day'"
        [class.active]="view === 'day'">
        Day
      </div>
    </div>
  </div>
</div>
<br>
<div [ngSwitch]="view">
  <mwl-calendar-month-view
    *ngSwitchCase="'month'"
    [viewDate]="viewDate"
    [events]="events"
    [refresh]="refresh"
    [activeDayIsOpen]="activeDayIsOpen"
    (dayClicked)="dayClicked($event.day)"
    (eventClicked)="handleEvent('Clicked', $event.event)"
    (eventTimesChanged)="eventTimesChanged($event)">
  </mwl-calendar-month-view>
  <mwl-calendar-week-view
    *ngSwitchCase="'week'"
    [viewDate]="viewDate"
    [events]="events"
    [refresh]="refresh"
    (eventClicked)="handleEvent('Clicked', $event.event)"
    (eventTimesChanged)="eventTimesChanged($event)">
  </mwl-calendar-week-view>
  <mwl-calendar-day-view
    *ngSwitchCase="'day'"
    [viewDate]="viewDate"
    [events]="events"
    [refresh]="refresh"
    (eventClicked)="handleEvent('Clicked', $event.event)"
    (eventTimesChanged)="eventTimesChanged($event)">
  </mwl-calendar-day-view>
</div>

<br><br><br>

<h3>
  Edit events
  <button
    class="btn btn-primary pull-right"
    (click)="addEvent()">
    Add new
  </button>
  <div class="clearfix"></div>
</h3>

<table class="table table-bordered">

  <thead>
    <tr>
      <th>Title</th>
      <th>Primary color</th>
      <th>Secondary color</th>
      <th>Starts at</th>
      <th>Ends at</th>
      <th>Remove</th>
    </tr>
  </thead>

  <tbody>
    <tr *ngFor="let event of events; let index = index">
      <td>
        <input
          type="text"
          class="form-control"
          [(ngModel)]="event.title"
          (keyup)="refresh.next()">
      </td>
      <td>
        <input
          type="color"
          [(ngModel)]="event.color.primary"
          (change)="refresh.next()">
      </td>
      <td>
        <input
          type="color"
          [(ngModel)]="event.color.secondary"
          (change)="refresh.next()">
      </td>
      <td>
        <input
          class="form-control"
          type="text"
          mwlFlatpickr
          [(ngModel)]="event.start"
          (ngModelChange)="refresh.next()"
          [altInput]="true"
          [convertModelValue]="true"
          [enableTime]="true"
          dateFormat="Y-m-dTH:i"
          altFormat="F j, Y H:i"
          placeholder="Not set">
      </td>
      <td>
        <input
          class="form-control"
          type="text"
          mwlFlatpickr
          [(ngModel)]="event.end"
          (ngModelChange)="refresh.next()"
          [altInput]="true"
          [convertModelValue]="true"
          [enableTime]="true"
          dateFormat="Y-m-dTH:i"
          altFormat="F j, Y H:i"
          placeholder="Not set">
      </td>
      <td>
        <button
          class="btn btn-danger"
          (click)="events.splice(index, 1); refresh.next()">
          Delete
        </button>
      </td>
    </tr>
  </tbody>

</table>

Sunt junior cu Angular 6 inca nu imi dau seama unde gafez e un proiect personal il fac pentru mine sa am ce prezenta la interviuri. Daca aveti vreo idee ce fel de varza calita e asta primesc recomandari cu drag.
Vibe bun si multumesc anticipat!

(István F.) #2

Problema ta e cu directiva [view]=“view”, unde l-ai definit sau in ce fisier il gasesti ?

(Andrei Luca) #3

Declari modulul calendar.module in care exporti componenta calendar.component.
Apoi tu vrei sa folosesti componenta asta undeva in alta parte (in app.module presupun). Nu crezi ca in app.module.ts ar trebui sa importi calendar.module? Nu vad sa fi importat modulul.
@isti37 cred ca directiva [view] vine de la libraria aia pe care vrea el s-o foloseasca (care e importata in calendar.module)

(Damian Florescu) #4

Deci am facut asa:
in app.module.ts

import {CalendarModule} from './calendar/calendar.module';
........
 imports: [
    BrowserModule,
    CalendarModule,
........

apoi in calendar.module.ts

import 'flatpickr/dist/flatpickr.css';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { CalendarModule } from 'angular-calendar';
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap/modal/modal.module';
import { FlatpickrModule } from 'angularx-flatpickr';
import { CalendarComponent } from './calendar.component';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    NgbModalModule.forRoot(),
    FlatpickrModule.forRoot(),
    CalendarModule.forRoot()
  ],
  declarations: [CalendarComponent],
  exports: [CalendarComponent]
})
export class CalendarModule {}

Imi da eroare CalendarModule{} zice ca a fost deja importat iar daca il scot din calendar.module.ts nu imi mai merge CalendarModule.forRoot()

(Ovidiu Grigoras) #5

scoate CalendarModule din calendar.module.ts si pune la imports in app.module.ts CalendarModule.forRoot().
Cred ca merg toate 3 mutaet si ngbModalModule si FlatpickrModule mutate dincolo.

(Damian Florescu) #6

Imi cere sa declar metoda pentru Calendar.Module.forRoot() Atasez mai jos o poza

Pe langa asta in app.module.ts tot codul este

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Directive, ElementRef, Input } from '@angular/core';
import { AngularFireModule } from 'angularfire2';
import { environment } from '../environments/environment';
import { NgModel, FormsModule } from '@angular/forms';
import { DragAndDropModule } from 'angular-draggable-droppable';
import { ResizeEvent } from 'angular-resizable-element';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
// tslint:disable-next-line:max-line-length
import {MatButtonModule, MatCheckboxModule, MatToolbarModule, MatSidenavModule, MatIconModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule} from '@angular/material';
import {LayoutModule} from '@angular/cdk/layout';
import { SidenavComponent } from './sidenav/sidenav.component';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TableComponent } from './table/table.component';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { AngularFireStorageModule } from 'angularfire2/storage';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { CoreModule } from './core/core.module';
import { UserProfileComponent } from './user-profile/user-profile.component';
import { CalendarComponent } from './calendar/calendar.component';
import { ResizableModule } from 'angular-resizable-element';
import {CalendarModule} from './calendar/calendar.module';

@NgModule({
  declarations: [
    AppComponent,
    SidenavComponent,
    DashboardComponent,
    TableComponent,
    UserProfileComponent,
    CalendarComponent,
  ],
  imports: [
    BrowserModule,
    CalendarModule,
    CalendarModule.forRoot(),
    ResizableModule,
    Input,
    [DragAndDropModule.forRoot()],
    AppRoutingModule,
    CoreModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFirestoreModule, // imports firebase/firestore, only needed for database features
    AngularFireAuthModule, // imports firebase/auth, only needed for auth features,
    AngularFireStorageModule, // imports firebase/storage only needed for storage features
    AppRoutingModule,
    [MatButtonModule, MatCheckboxModule],
    [BrowserAnimationsModule],
    LayoutModule,
    BrowserAnimationsModule,
    MatToolbarModule,
    MatButtonModule,
    MatSidenavModule,
    MatIconModule,
    MatListModule,
    MatGridListModule,
    MatCardModule,
    MatMenuModule,
    MatTableModule,
    MatPaginatorModule,
    MatSortModule,
  ],
  exports: [ RouterModule ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

(Red) #7

Asta se mai numește programare? Așa arată viitorul ăsta cu Javascript pe frontend cât și pe backend?

(Andrei Luca) #8

De ce CalendarModule este un…modul?
Vei refolosi componenta asta de calendar? ->>> muta in shared.module.ts
Nu vei refolosi componenta asta? ->>> in app.module.ts :

import { CalendarModule } from 'angular-calendar';
@NgModule({
  imports: [BrowserAnimationsModule, CalendarModule.forRoot()]
})

Sterge calendar.module.ts si o sa folosesti componenta asta ca oricare alta.

1 Like
(Andrei Luca) #9

Nu prea inteleg intrebarea sincer sa fiu…
Punem doar assembly ca fiind programare atunci?
Oh boy, in cazul asta o sa fii surprins de ce o sa mai apara in viitor…

1 Like
(Red) #10

Păi programarea are if-uri, while-uri, funcții, clase. Acolo am văzut o mare de a ia valoare array de b. Ca și Java-ul și fișierele lui XML.

Anyway, personally I get it. Dar îmi fac grijă de colegi. Abia înțeleg să folosească o funcție, dacă viitorul stă în așa o structurare a codului, mai bine ies la pensie că numai probleme voi avea.

(Ovidiu Grigoras) #11

@RedGuard Well, eu nu vad unde e problema ta sincer sa fiu. Ce anume din cod ti se pare asa dezastruos incat sa-ti faci grij pentru colegii tai ?
@misterflorescu - ce-a zis @Andrei_Luca - plus ca iti da eroare ca ai lasat CalendarComponet acolo, eu ziceam sa il scoti si sa-l pui in app.module.ts

(Red) #12

Se pare că numai eu am lucrat cu oameni care aveau 0 interes să programeze pe poziții de seniori.

1 Like
(Damian Florescu) #13

In linkul catre angular-calendar era un modul si nu am reusit sa import cu bine in app.module.ts totul asa ca am generat calendar.module.ts sa imi simplific treaba sa fie cat mai asemanator cu cel de pe git-ul acela.

(Damian Florescu) #14

Ok. Urmand sfatul tau am ajuns aici acum:

Also daca las visual studio code sa imi genereze ce e necesar method not implemented

(mrapi) #15

@RedGuard: Daca te referi strinct la Angular,da are clase,if-uri,funcții,este frumos organizat.ce ai vazut acolo este fisier de configurare a dependentelor aplicatiei sa zicem asa.Angular foloseste typescript,un javascript cu imbunatatiri,daca vrei poti scrie chiar javascript.Si eu m-am speriat cand l-am vazut prima data,dar imi place mai mult decat React.

(Damian Florescu) #16

@mrapi vizavi de chestia asta cum e react fata de angular ? Mai stabil ? Sare del a o versiune la alta cum sare angular din 6 in 6 luni sau e mai stabil.

(Andrei Luca) #17

Dute in codul sursa din librarie (src/node_modules -> … ) si asigura-te ca functia aia forRoot() e implementata (exista niste pluginuri pt vscode sa ai goToDefinition cand apesi ctrl + click pe o clasa).
Asigura-te ca CalendarModule e importat nu din calendar.module.ts (care ar trebui sa fie sters de altfel) ci e importat din libraria aia.

(Georgiana Gligor) #18

Eu folosesc (cu intermitente) React chiar de cand a aparut. Desi in prima jumatate de an a fost “moartea” pt ca in fiecare zi apareau noi versiuni care nu erau compatibile cu cele vechi (indeosebi la librarii, dar si la React in sine), consider ca in ultimii 2 ani e foarte stabil si prietenos. Adica nu a trebuit sa reinvat nimic, doar sa adaug cunostinte / librarii / abordari on top of cele vechi.

E de nepretuit sa am teste de integrare, care imi verifica functionarea aplicatiei dpdv al utilizatorului final, pt ca in felul acesta pot face upgrade la cate o librarie / versiune de React si verifica distinct compatibilitatea, rezolvand o singura problema o data. Nu a prea fost cazul in ultima jumatate de an.

(Damian Florescu) #19

Ok problem solved. M-am prins CalendarModule.forRoot() era numai daca voiam sa trag calendarul prin alte pagini. Ok. Ideea e ca acum ma confrunt cu urmatoarea:
In consola primesc eroarea asta

Uncaught Error: Unexpected value 'PropDecoratorFactory' imported by the module 'AppModule'. Please add a @NgModule annotation.

Mentionez ca faptul ca postez aici inseamna ca nu am reusit sa gasesc pe google.

(Andrei Luca) #20
  1. Ai facut Angular Tour of Heroes?
  2. Inteleg ca vrei sa inveti Angular. Presupun ca n-ai experienta cu Angular. De ce iti extra-complici codul cu Firebase, Material si alte librarii care n-au niciun rost pentru tine acum?
  3. Nu vad nicaieri in codul tau unde folosesti tu acest factory.
    Sfatul meu : elimina lucrurile care nu sunt esentiale in acest moment la proiectului -> material, firebase
    Lasa codul cat mai gol ca sa ne fie si noua mai usor sa citim si sa incercam sa identificam problema.
    Posibil sa fie de la faptul ca tu importi Input din @angular/core in app.module.ts -> imports : [Input]
    Nu stiu sa-ti zic la prima vedere ce e Input, dar e f posibil sa nu fie un modul (in imports ar trebui sa ai doar module).
1 Like