Ways to attain a similar format - input map

After pressing the save button, I am aiming to achieve the following effect:

"timeTable":{
    "0": [{"from":"08:00","to":"12:00"}, {"from":"14:00","to":"18:20"}],
    "1": [{"from":"08:00","to":"16:00"}]
.....
  }

I'm having trouble achieving this. Could someone assist me in getting the desired result as shown below:

{"0":{
   "0":{"from":"00:00","to":"23:00"}},
    "1":{"0":{"from":"08:00","to":"16:00"}}}
}

I'm unsure of how to modify the getTimeline function... Check here for reference.

import { Component, OnInit, VERSION } from '@angular/core';

interface Row {
  name: string;
  items: number[];
  active: boolean;
  day: number;
}
interface HourScheduleDefinitionModel {
  from: string;
  to: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  arr: Row[] = [
    { name: 'Monday', day: 0, items: new Array(24).fill(1), active: true },
    { name: 'Tuesday', day: 1, items: new Array(24).fill(0), active: false },
    {
      name: 'Wednesday',
      day: 2,
      items: new Array(24).fill(0),
      active: false,
    },
    { name: 'Thursday', day: 3, items: new Array(24).fill(0), active: false },
    { name: 'Friday', day: 4, items: new Array(24).fill(0), active: false },
    { name: 'Saturday', day: 5, items: new Array(24).fill(0), active: false },
    { name: 'Sunday', day: 6, items: new Array(24).fill(0), active: false },
  ];
  timeTable2: Map<number, Array<HourScheduleDefinitionModel>>;
  timeTable: HourScheduleDefinitionModel[][];

  // example mentioned above

  ngOnInit() {
    this.arr.forEach((row: Row, index: number) => {
      if (this.arr[index].items.every((col) => col === 1)) {
        row.active = true;
      }
    });
  }

  click(day: number, range: number) {
    this.arr[day].items[range] = this.arr[day].items[range] === 1 ? 0 : 1;
    this.arr[day].active = this.arr[day].items.every((col) => col === 1);
  }

  toggleRow(day: number): void {
    this.arr[day].items.fill(this.arr[day].active ? 0 : 1);
    this.arr[day].active = !this.arr[day].active;
  }

  getTimeline = () => {
    const result = [];
    console.log(this.arr);
    for (const item of this.arr) {
      let start = -1,
        timeTable = [];
      for (let i = 0; i < item.items.length; i++) {
        if (item.items[i] === 1) {
          if (start === -1) {
            start = i;
          }
        } else {
          if (start !== -1) {
            timeTable.push({
              from: start < 10 ? '0' + start + ':00' : start + ':00',
              to: i < 10 ? '0' + (i - 1) + ':00' : i - 1 + ':00',
            });
            start = -1;
          }
        }
        if (start !== -1 && i === item.items.length - 1) {
          timeTable.push({
            from: start < 10 ? '0' + start + ':00' : start + ':00',
            to: '23:00',
          });
        }
      }
      result.push({
        ...timeTable,
      });
    }
    return result;
  };

  save() {
    this.timeTable = this.getTimeline();
    console.log(this.timeTable);
    let val = { ...this.timeTable };
    console.log(JSON.stringify(val));
  }
}

Answer №1

Would you consider an alternative approach like this?

// Custom Row interface definition
interface Row {
    name: string;
    items: number[];
    active: boolean;
    day: number;
}

// Sample data provided
const arr: Row[] = [
    { name: 'Monday', day: 0, items: new Array(24).fill(1), active: true },
    { name: 'Tuesday', day: 1, items: new Array(24).fill(0), active: false },
    { name: 'Wednesday', day: 2, items: new Array(24).fill(0), active: false },
    { name: 'Thursday', day: 3, items: new Array(24).fill(0), active: false },
    { name: 'Friday', day: 4, items: new Array(24).fill(0), active: false },
    { name: 'Saturday', day: 5, items: new Array(24).fill(0), active: false },
    { name: 'Sunday', day: 6, items: new Array(24).fill(0), active: false },
];

// Interface for representing a period in time (e.g. {"from":"08:00","to":"12:00"})
interface Period {
    from: string;
    to: string;
}

// Function to convert an array of 24 numbers into an array of Periods
const getPeriodsForDay = (items: number[]): Period[] => {
    const result: Period[] = [];
    let i = 0;
    let periodStartIndex: number | null = null;
    let isCurrentIndexActive = false;

    while (i < items.length) {
        isCurrentIndexActive = items[i] === 1;
        if (isCurrentIndexActive && periodStartIndex == null)
        {
            periodStartIndex = i;
        } else if (!isCurrentIndexActive && periodStartIndex != null) {
             result.push({ from: convertToTimeString(periodStartIndex), to: convertToTimeString(i) });
        }
        i++;
    }

    if (isCurrentIndexActive && periodStartIndex != null) {
        result.push({ from: convertToTimeString(periodStartIndex), to: convertToTimeString(i - 1) });
    }
    return result;
}

// Function to format index into desired time string (e.g. 3 would become "03:00")
const convertToTimeString = (index: number) => {
    return `${index.toString().padStart(2, "0")}:00`
};

// Function to create a wrapper around the time table results
const getTimeTable = (rows: Row[]) => {
    const timeTable: { [key: string]: Period[] } = {};
    for(let i = 0; i < rows.length; i++) {
        timeTable[i] = getPeriodsForDay(rows[i].items);
    }

    return {
        timeTable: timeTable
    }
};

console.log(getTimeTable(arr));

Explore Typescript Playground here

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 steps can be taken to prevent a tab click from causing issues?

Within my application, there is a tab group that contains four tabs: <ion-tabs> <ion-tab [root]="tab1Root" tabTitle="Programmes" tabIcon="icon-programmes"></ion-tab> <ion-tab [root]="tab2Root" (ionSelect)="studioCheck()" tabTitle= ...

What is the reason behind Angular Material sort buttons showing arrows, yet failing to actually sort the columns?

Looking to make my table sortable, I've been using the https://material.angular.io/components/sort/overview. The "Sort Header" feature is working on other tables in the web-app, I've gone through the documentation, watched tutorials, but for some ...

The function e.preventDefault() appears to be ineffective when applied to both the submit button and anchor tag within an

In my ASP.Net Core MVC App View <form> <div class="container"> <div class="row"> <div class="col-md-offset-2 col-md-4"> <div class="form-group"> <input type="text" class="form-contr ...

Creating a personal TypeScript language service extension in Visual Studio Code

Currently, I am working on developing a TSserver plugin in VSCode and struggling to get the server to load my plugin. I have experimented with setting the path in tsconfig.json to both a local path and a path to node_modules, but it still isn't worki ...

The element 'md-chips' from Angular2 material is unrecognized

I am currently developing an Angular2 application utilizing @angular/material 2.0.0-beta.2 and I am facing a challenge in implementing Chips, as I keep receiving the error message 'md-chips' is not a known element. Here are the steps I have taken ...

Angular: Safely preserving lengthy content without the use of a database

As a beginner working on an Angular 11 educational website with approximately 20 static articles, I created a component template for the articles to receive text inputs. However, I am wondering if there is a more efficient way to handle this. Is there a ...

Utilizing Angular and ASP .Net Web Api in conjunction with Plesk hosting platform

I have successfully created a website using Angular and .NET Framework 5.0. I was able to publish the Angular portion on Plesk and it is working correctly, but I am facing challenges in publishing the .NET Framework app and connecting it with Angular. ...

Padding for the doughnut chart in Chart.js canvas

My current setup includes a canvas featuring a doughnut chart created with chart.js enclosed in a div element that displays like this: The canvas has a red background to enhance visibility. Currently, the chart is centered within the canvas with additiona ...

Error Message: "Unable to locate module for Angular 5 UI Components packaging"

In the process of developing UI Components to be used in various web projects throughout the company, we are aiming to publish these components as an npm package on our local repository. It is crucial for us to include the sources for debugging purposes. F ...

Customizing the initial page layout in Elm

I am new to Elm and I need help with a particular issue. Can someone provide guidance or direct me to a useful resource for solving this problem? The challenge I’m facing involves editing the start page of a website by removing specific elements, as list ...

Using the pipe operator in RXJS to transform an Event into a KeyboardEvent

I'm encountering an error when trying to add a keydown event and convert the parameter type from Event to KeyboardEvent as shown below. fromEvent(document, "keydown") .pipe<KeyboardEvent, KeyboardEvent>( filter((event) => even ...

Encountering an Angular 12 error 401 upon refreshing the page

Currently, I am working on a login form using angular 12 with Spring Boot that includes basic authentication spring security. When a user successfully logs in, they are directed to the main page which offers CRUD actions as depicted in the images linked be ...

Using TypeScript to create a generic function that returns a null value

In my Typescript code, I have the following function: In C#, you can use default(T), but I'm not sure what the equivalent is in Typescript. public Base { ... } public Get<T extends Base>(cultura: string): T[] { let res = null; try ...

Changes in tabs are discarded when switching between them within Material UI Tabs

I have been experiencing an issue with the Material UI tab component where changes made in tabs are discarded when switching between them. It seems that after switching, the tabs are rendered again from scratch. For example, let's say I have a textFie ...

Unable to retrieve rxjs resource

After upgrading to rxjs 5.4.3, I encountered an error in the browser. Despite having "rxjs": "5.4.3" installed in my package.json, I cannot seem to resolve this error message. Here's the content of my ts file: import { Injectable ...

Error in refreshing the deployment package of angular 4 on an Apache server

At the moment, my Angular application runs on an Apache server at the 'http://localhost' root or index page. However, when I refresh the inner page 'http://localhost/dms-data/summary-of-findings', the browser displays Page Not Found T ...

Resolving undefined in Ionic 4: Returning Data from Modal

I'm attempting to create a modal window that utilizes a radio group. When a user selects a value from the radio group, I want the modal to return the selected object. Here is the code for the radio group page and HTML: export class PopoverstationsPa ...

Invoking a Components function from a Service in Angular may lead to a potential cyclic dependency issue

I am facing a challenge where I need to call a function from my filterComponent(component) within my engagementService(service). The function in my filterComponent accesses an array that is located within the engagementService. It uses the data from this ...

Guiding you through the process of dynamically defining a port in proxy.conf.json or proxy.conf.js

Starting my Angular4 application for development involves running npm run start, where start is defined as "start": "ng serve --proxy=proxy.conf.json". Within the proxy.conf.json file, I have: { "/api/**": { "target": "http://localhost:80 ...

How can Angular 2 e2e tests maintain respect for their execution order?

What's the best way to ensure that Angular 2 e2e tests run in the order they are declared? I am currently using Angular-cli for my project. ...