crud/frontend/restapi

*//good morning to all of syncfusion, I come across this message trying to take some questions regarding the crud of the frontend I'm building a system for my completion of the bachelor course, my project is all structured in angular / and angular-material, and now in also syncfusion / ej-schedule, my doubts is how to access my bank mongodb restapi in the backend because the structure of syncfusion is quite different from the angular, so I need to know more how do I assemble the whole structure in the frontend, here are two files to further adapt the example I need!?//*

import { Component, ViewChild, ViewEncapsulation, Inject, OnInit } from '@angular/core';
import { extend, Internationalization,isNullOrUndefined } from '@syncfusion/ej2-base';
import { DropDownListComponent } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxComponent } from '@syncfusion/ej2-angular-inputs';
import {
    ScheduleComponent, MonthService, DayService, WeekService, WorkWeekService, AgendaService,
    MonthAgendaService, ResourcesModel, CellClickEventArgs, CurrentAction, EventSettingsModel,PopupOpenEventArgs
from '@syncfusion/ej2-angular-schedule';
import { quickInfoTemplateData } from '../data';



@Component({
  selector: 'app-contact-schedule',
  providers: [DayServiceWeekServiceWorkWeekServiceMonthServiceAgendaServiceMonthAgendaService],

  template: `
   <mat-toolbar>
  <button mat-icon-button class="example-icon" aria-label="Example icon-button with menu icon" [routerLink]="['/Header']">
    <mat-icon>home</mat-icon>
  </button>
  <span>Ecoplace | Agenda</span>
  <span class="example-spacer"></span>
  <button mat-icon-button class="example-icon favorite-icon" aria-label="Example icon-button with heart icon">
    <mat-icon>favorite</mat-icon>
  </button>
  <button mat-icon-button class="example-icon" aria-label="Example icon-button with share icon">
    <mat-icon>share</mat-icon>
  </button>
  
</mat-toolbar>

  <ejs-schedule #scheduleObj width='100%' height='550px' [selectedDate]="selectedDate" [eventSettings]="eventSettings"
  (popupOpen)="onPopupOpen($event)">


  <ng-template #quickInfoTemplatesHeader let-data>
    <div *ngIf="data.elementType == 'event'">
      <div class="e-popup-header" style="background-color: rgb(234, 122, 87);">
        <div class="e-header-icon-wrapper">
          <button (click)="onEditClick($event)" ejs-button class="e-edit e-icons e-control e-btn e-lib e-flat e-round e-small e-icon-btn" title="Edit">
              <span class="e-btn-icon e-icons e-edit-icon"></span>
          </button>
          <button (click)="onDeleteClick($event)" ejs-button class="e-delete e-icons e-control e-btn e-lib e-flat e-round e-small e-icon-btn" title="Delete">
              <span class="e-btn-icon e-icons e-delete-icon"></span>
          </button>
        
        </div>
        <div class="e-subject-wrap">
          <div class="e-subject e-text-ellipsis" [title]="data.Subject">
            <div [innerHTML]="data.Subject"></div>
          </div>
        </div>
      </div>
    </div>
  </ng-template>

</ejs-schedule>
  `,
  
  styleUrls: ['./contact-schedule.component.css'],
  encapsulation: ViewEncapsulation.None,

})
export class ContactScheduleComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }
  @ViewChild('scheduleObj')
  public scheduleObj: ScheduleComponent;
  public eventSettings: EventSettingsModel = {
      dataSource: quickInfoTemplateData
  };
  public selectedDate: Date = new Date(202005);
  private selectionTarget: Element;
     public roomData: Object[] = [
      { Name: 'Jammy', Id: 1, Capacity: 20, Color: '#ea7a57', Type: 'Conference' },
      { Name: 'Tweety', Id: 2, Capacity: 7, Color: '#7fa900', Type: 'Cabin' },
      { Name: 'Nestle', Id: 3, Capacity: 5, Color: '#5978ee', Type: 'Cabin' },
      { Name: 'Phoenix', Id: 4, Capacity: 15, Color: '#fec200', Type: 'Conference' },
      { Name: 'Mission', Id: 5, Capacity: 25, Color: '#df5286', Type: 'Conference' },
      { Name: 'Hangout', Id: 6, Capacity: 10, Color: '#00bdae', Type: 'Cabin' },
      { Name: 'Rick Roll', Id: 7, Capacity: 20, Color: '#865fcf', Type: 'Conference' },
      { Name: 'Rainbow', Id: 8, Capacity: 8, Color: '#1aaa55', Type: 'Cabin' },
      { Name: 'Swarm', Id: 9, Capacity: 30, Color: '#df5286', Type: 'Conference' },
      { Name: 'Photogenic', Id: 10, Capacity: 25, Color: '#710193', Type: 'Conference' }
  ];
  public onPopupOpen(args: PopupOpenEventArgs): void {
      this.selectionTarget = null;
      this.selectionTarget = args.target;
  }
  public onDetailsClick(): void {
      this.onCloseClick();
      const data: Object = this.scheduleObj.getCellDetails(this.scheduleObj.getSelectedElements()) as Object;
      this.scheduleObj.openEditor(data'Add');
  }
  public onAddClick(): void {
      this.onCloseClick();
      const data: Object = this.scheduleObj.getCellDetails(this.scheduleObj.getSelectedElements()) as Object;
      const eventData: { [key: string]: Object } = this.scheduleObj.eventWindow.getObjectFromFormData('e-quick-popup-wrapper');
      this.scheduleObj.eventWindow.convertToEventData(data as { [key: string]: Object }, eventData);
      eventData.Id = this.scheduleObj.eventBase.getEventMaxID() as number + 1;
      this.scheduleObj.addEvent(eventData);
  }
  public onEditClick(args: any): void {
      if (this.selectionTarget) {
    let eventData: { [key: string]: Object } = this.scheduleObj.getEventDetails(this.selectionTarget) as { [key: string]: Object };
    let currentAction: CurrentAction = 'Save';
    
    // console.log("TEST", eventData);

    this.scheduleObj.openEditor(eventData, currentAction);
  }
  }
  public onDeleteClick(args: any): void {
      this.onCloseClick();
      if (this.selectionTarget) {
      const eventData: { [key: string]: Object } = this.scheduleObj.getEventDetails(this.selectionTarget) as { [key: string]: Object };
      let currentAction: CurrentAction;
      if (!isNullOrUndefined(eventData.RecurrenceRule) && eventData.RecurrenceRule !== '') {
          currentAction = args.target.classList.contains('e-delete-series'? 'DeleteSeries' : 'DeleteOccurrence';
      }
      this.scheduleObj.deleteEvent(eventData, currentAction);
      }
  }
  public onCloseClick(): void {
      this.scheduleObj.quickPopup.quickPopupHide();
  }

}
*//api.service.ts//*







Attachment: api.service.ts_f4a6dca5.rar

5 Replies 1 reply marked as answer

HB Hareesh Balasubramanian Syncfusion Team October 1, 2020 09:15 AM UTC

Hi Armando, 
 
Greetings from Syncfusion Support…! 
   
We have validated your shared query “my doubts is how to access my bank mongodb restapi in the backend” at our end. And we have prepared CRUD sample, in that events for the Scheduler has been bind from MongoDB service and the sample can be downloaded from the following link. 
  
   
In the above sample, we have added CRUD actions code snippet in server.js. 
 
var MongoClient = require('mongodb').MongoClient; 
const express = require('express'); 
const bodyParser = require('body-parser'); 
const app = express(); 
var url = "mongodb://localhost:27017/"; 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })) 
app.listen(5000, function () { 
    console.log('listening on 5000') 
}) 
app.use(express.static(__dirname)) 
 
MongoClient.connect(url, function (err, db) { 
    if (err) throw err; 
    var dbo = db.db("mydb"); 
    app.use(function (req, res, next) { 
        res.header("Access-Control-Allow-Origin", "*"); 
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
        next(); 
    }); 
    app.post("/GetData", (req, res) => { 
        dbo.collection('ScheduleData').find({}).toArray((err, cus) => { 
            res.send(cus); 
        }); 
    }); 
    app.post("/BatchData", (req, res) => { 
        console.log(req.body); 
        var eventData = []; 
        if (req.body.action == "insert" || (req.body.action == "batch" && req.body.added.length > 0)) { 
            (req.body.action == "insert") ? eventData.push(req.body.value) : eventData = req.body.added; 
            for (var i = 0; i < eventData.length; i++) { 
                var sdate = new Date(eventData[i].StartTime); 
                var edate = new Date(eventData[i].EndTime); 
                eventData[i].StartTime = sdate; 
                eventData[i].EndTime = edate; 
                dbo.collection('ScheduleData').insertOne(eventData[i]); 
            } 
        } 
        if (req.body.action == "update" || (req.body.action == "batch" && req.body.changed.length > 0)) { 
            (req.body.action == "update") ? eventData.push(req.body.value) : eventData = req.body.changed; 
            for (var i = 0; i < eventData.length; i++) { 
                delete eventData[i]._id; 
                var sdate = new Date(eventData[i].StartTime); 
                var edate = new Date(eventData[i].EndTime); 
                eventData[i].StartTime = sdate; 
                eventData[i].EndTime = edate; 
                dbo.collection('ScheduleData').updateOne({ "Id": eventData[i].Id }, { $set: eventData[i] }); 
            } 
        } 
        if (req.body.action == "remove" || (req.body.action == "batch" && req.body.deleted.length > 0)) { 
            (req.body.action == "remove") ? eventData.push({ Id: req.body.key }) : eventData = req.body.deleted; 
            for (var i = 0; i < eventData.length; i++) { 
                dbo.collection('ScheduleData').deleteOne({ "Id": eventData[i].Id }); 
            } 
        } 
        res.send(req.body); 
    }); 
}); 
  
Note: We have removed the local offset time before inserting and updating the events in the database collection to render the appointments without considering system UTC in the scheduler.  
   
In the below code we have given the GetData and BatchData url path to initial fetching and for performing CRUD actions using UrlAdaptor and assigned it to the scheduler datasource. 
 
    private dataManager: DataManager = new DataManager({  
    url: 'http://localhost:5000/GetData',  
    crudUrl: 'http://localhost:5000/BatchData',  
    adaptor: new UrlAdaptor,  
    crossDomain: true  
  });  
    ngOnInit(): void { 
    this.selectedDate = new Date(2018, 1, 14); 
    this.eventSettings = { dataSource: this.dataManager }; 
  } 
  
Steps to run the sample:  
  1. Run MongoDB and create the collection named ‘ScheduleData’ in ‘mydb’ database.
  2. Run the below comments.
npm install  
npm run server  
npm start  
   
Please try the above sample and let us know if you need further assistance.  
   
Regards,  
Hareesh 



AR Armando October 15, 2020 05:16 PM UTC

good morning to all syncfusion and hareesh team, I managed to successfully implement only that the delete is not running, could help me with this part without more attentively!

In the backend console is showing this way, more in the schedule and popup does not perform the delete function"
{
  changed: [],
  added: [],
  deleted: [
    {
      _id: '5f887869454b351920109ee6',      
      Subject: '20 litros',
      Location: 'cep: 05336-060',
      StartTime: '2020-02-12T11:00:00.000Z',      EndTime: '2020-02-12T12:30:00.000Z',  
      IsAllDay: false,
      StartTimezone: null,
      EndTimezone: null,
      Description: 'falar com ronaldo ref: ao lado da padaria stella',
      RecurrenceRule: null,
      Id: 3,
      Guid: '09bc6183-736b-92d3-eaba-03a0182b95c1'
    }
  ],
  action: 'batch',
  params: {
    StartDate: '2020-02-06T03:00:00.000Z',  
    EndDate: '2020-02-13T03:00:00.000Z'     
  },
  StartDate: '2020-02-06T03:00:00.000Z',    
  EndDate: '2020-02-13T03:00:00.000Z'       
}
{
  changed: [],
  added: [],
  deleted: [
    {
      _id: '5f887869454b351920109ee6',      
      Subject: '20 litros',
      Location: 'cep: 05336-060',
      StartTime: '2020-02-12T11:00:00.000Z',      EndTime: '2020-02-12T12:30:00.000Z',  
      IsAllDay: false,
      StartTimezone: null,
      EndTimezone: null,
      Description: 'falar com ronaldo ref: ao lado da padaria stella',
      RecurrenceRule: null,
      Id: 3,
      Guid: '6b9cc4b6-7119-ae59-bb1d-cf822aa98307'
    }
  ],
  action: 'batch',
  params: {
    StartDate: '2020-02-09T03:00:00.000Z',  
    EndDate: '2020-02-16T03:00:00.000Z'     
  },
  StartDate: '2020-02-09T03:00:00.000Z',    
  EndDate: '2020-02-16T03:00:00.000Z'       
}

In Navigation Google example: Response Headers!


    1. HTTP/1.1 200 OK X-Powered-By: Express Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept Content-Type: application/json; charset=utf-8 Content-Length: 575 ETag: W/"23f-ukZDFwD5u6nWjB6H22rGJiZEV/U" Date: Thu, 15 Oct 2020 17:05:08 GMT Connection: keep-alive
  1. Request Headersview source
    1. Accept:
      */*
    2. Accept-Encoding:
      gzip, deflate, br
    3. Accept-Language:
      en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7,en-GB;q=0.6
    4. Connection:
      keep-alive
    5. Content-Length:
      575
    6. Content-Type:
      application/json; charset=UTF-8
    7. Host:
      localhost:5000
    8. Origin:
      http://localhost:4200
    9. Referer:
      http://localhost:4200/
    10. Sec-Fetch-Dest:
      empty
    11. Sec-Fetch-Mode:
      cors
    12. Sec-Fetch-Site:
      same-site
    13. User-Agent:
      Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38
  2. Request Payloadview source
    1. {changed: [], added: [],…}
      1. EndDate"2020-02-16T03:00:00.000Z"
      2. StartDate"2020-02-09T03:00:00.000Z"
      3. action"batch"
      4. added[]
      5. changed[]
      6. deleted[{_id: "5f887869454b351920109ee6", Subject: "20 litros", Location: "cep: 05336-060",…}]
        1. 0{_id: "5f887869454b351920109ee6", Subject: "20 litros", Location: "cep: 05336-060",…}
          1. Description"falar com ronaldo ref: ao lado da padaria stella"
          2. EndTime"2020-02-12T12:30:00.000Z"
          3. EndTimezonenull
          4. Guid"6b9cc4b6-7119-ae59-bb1d-cf822aa98307"
          5. Id3
          6. IsAllDayfalse
          7. Location"cep: 05336-060"
          8. RecurrenceRulenull
          9. StartTime"2020-02-12T11:00:00.000Z"
          10. StartTimezonenull
          11. Subject"20 litros"
          12. _id"5f887869454b351920109ee6"
      7. params{StartDate: "2020-02-09T03:00:00.000Z", EndDate: "2020-02-16T03:00:00.000Z"}
        1. EndDate"2020-02-16T03:00:00.000Z"
        2. StartDate"2020-02-09T03:00:00.000Z"



HB Hareesh Balasubramanian Syncfusion Team October 16, 2020 06:40 AM UTC

Hi Armando, 

Thanks for the update. 

We have validated your shared query “delete is not running” at our end and suspect that you may not include the collectionName/Scheduler event fields properly at your server-side and that could be the reason for the reported problem. And also we have ensured CRUD functionalities at our end in our previously attached sample and it is properly working at our end and the same can be downloaded from the following link. 


[server.js] 
        if (req.body.action == "remove" || (req.body.action == "batch" && req.body.deleted.length > 0)) { 
            (req.body.action == "remove") ? eventData.push({ Id: req.body.key }) : eventData = req.body.deleted; 
            for (var i = 0; i < eventData.length; i++) { 
                dbo.collection('ScheduleData').deleteOne({ "Id": eventData[i].Id }); 
            } 
        } 

Note: Kindly run the MongoDB server first using “npm run server” and then the client sample using “npm start”. 

And for your further reference, we have taken a video demo of the above sample and it can be downloaded from the below link, 

Kindly try the above solution and if the issue still persists at your end kindly share the below details to serve you better?  
  
  • Replicate the issue in the above sample or else
  • Share the issue replicating sample (if possible)

Regards, 
Hareesh 


Marked as answer

AR Armando October 17, 2020 07:09 AM UTC

hareesh thank you i implanted your template with another template and it worked a lot, I apologize for my impertinence, without more attentively thank you!


NR Nevitha Ravi Syncfusion Team October 19, 2020 06:23 AM UTC

Hi Armando, 

You are most welcome 😊 , please let us know if you need any further assistance. 

Regards, 
Nevitha 


Loader.
Up arrow icon