Varun Sharma
Varun Sharma

Reputation: 4842

How to create multiple array based on row of .CSV file in Angular?

I am implementing Angular template for reading .CSV file and generating table. So I created two .CSV file, one for the header and second one for the table content.

For heading CSV file: header.csv

enter image description here

For data of table CSV file: tableContent.csv

enter image description here

Now I am able to read all data and converted into array, But I am getting into one array. I am sharing my code for more understanding.I have putted .csv file in assets folder.

app.component.ts

export class AppComponent {
  title = 'project';
  myData: any;
  myContent: any;
  constructor(private httpClient: HttpClient) { }
  ngOnInit() {
    this.httpClient.get('assets/header.csv', { responseType: 'text' }).subscribe(
      data => {
        this.myData = data.split("\n");
      }
    );
  }
  clicked(event) {
    console.log(event.srcElement.name);
    this.httpClient.get('assets/tableContent.csv', { responseType: 'text' }).subscribe(
      data => {
        this.myContent = data.split(",");
        let ab=this.myContent;
        console.log("------------>",ab);        
      }
    );
  }
}

app.component.html

<table id="customers">
  <tr>
    <th *ngFor="let dataheader of myData"><button (click)="clicked($event)" id={{dataheader}} name={{dataheader}}>{{dataheader}}</button></th>    
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
    <td>Germany</td>
  </tr>
</table>

Browser screen enter image description here

I want to create multiple object of array. like below:

[{
"myAccess":["myAccess","Prod","URL","[email protected]","Enable"]
},
{
"System":["System","Environment","URL","[email protected]","Enable"]
},
{
"OAM":["OAM","DEV","URL","[email protected]","Enable"]
},
{
"Mylogin":["Mylogin","prod","URL","[email protected]","Enable"]
}]

Table heading will comes from particular header.csv and data will comes from tableContent.csv. So Finally If i will click on the particular header so It will search into json object(which is read by tablecontent.csv). will show the particular result. Like if I will click on the myAccess so related myaccess data show in the table data.

Thanks in advance, Kindly share your idea.

Upvotes: 0

Views: 2535

Answers (3)

Supun De Silva
Supun De Silva

Reputation: 1487

This should solve your problem. Please handle errors better than me :D (Bootstrap being used for styling)

Component

import { Component, OnInit } from '@angular/core';
import { FileService } from './services/file.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
  title = 'temp-app';

  public headers = [];
  public data = {};

  public selectedHeader = null;
  constructor(private fileSvc: FileService) {

  }

  ngOnInit(): void {
    this.fileSvc.getHeaders().subscribe(
      data =>  {
        if (data != null && data.length > 0) {
          let headers = data.split('\n');
          headers = headers.filter(x => x.trim() !== '');
          for (const item of headers) {
            this.headers.push(item.trim());
          }
        } else {
          this.headers = [];
        }
      }
    );

    this.fileSvc.getData().subscribe(
      data =>  {
        if (data != null && data.length > 0) {
          const tempData = data;
          let rows = [];
          rows = tempData.split('\n');
          for (let row of rows) {
            if (row.trim() === '') {
              continue;
            }
            row = row.replace('\r', '')
            const rowSplits = row.split(',');
            this.data[rowSplits[0]] = rowSplits;
          }
        } else {
          this.data = {};
        }
      });
  }

  headerSeleced(header) {
    this.selectedHeader = header;
  }
}

Service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class FileService {

  constructor(private httpClient: HttpClient) {

  }

  public getHeaders() {
    return this.httpClient.get('assets/header.csv', { responseType: 'text' });
  }

  public getData() {
    return this.httpClient.get('assets/tableContent.csv', { responseType: 'text' });
  }
}

sample html

<div class="container">
  <div class="row">
    <div class="col-sm-12">
      <h3>Headers</h3>
    </div>
    <div *ngFor="let item of headers"
      class="col-sm-3 bg-secondary p-2 m-1 text-white btn"
      (click)="headerSeleced(item)">
      {{item}}
    </div>
  </div>
  <hr>
  <div class="row">
    <ng-container *ngFor="let item of data | keyvalue">
      <ng-container *ngIf="selectedHeader == item.key" >
        <div class="col-auto border">
          <b>{{item.key}}</b>
        </div>
        <div *ngFor="let prop of item.value" class="col-auto border">
          {{prop}}
        </div>
      </ng-container>
    </ng-container>
  </div>
</div>

Upvotes: 1

Aditya toke
Aditya toke

Reputation: 511

In order to remove the next line icon
enter image description here

You need to add this line in your app.component.ts

this.httpClient.get('assets/content.csv', { responseType: 'text' }).subscribe(
      data => {
             // add this line before the split
              data = data.replace(/[\r\n]/g,",");
             this.headerData = data.split(",").filter(Boolean);
      }
    );

First we will get the header data from CSV File

this.httpClient.get('assets/header.csv', { responseType: 'text' }).subscribe(
      data => {
             // add this line before the split
              data = data.replace(/[\r\n]/g,",");
             this.headerData = data.split(",").filter(Boolean);
      }
    );

In order to get the desired output, you can split the array according to your need.
As guess from your CSV file image, column length will be now based on this.headerData.length which will be dynamic

 for( let index = 0; index < this.myContent.length; index ++) {
           const value = this.myContent.splice(0,this.headerData.length);
          // now you got the value you can create structure according to your need
 }


Read more about Array.Splice() as it help allot while creating sub-array

Upvotes: 0

Aakash Garg
Aakash Garg

Reputation: 10979

export class AppComponent {
  title = 'project';
  myData: any;
  myContent = [];
  constructor(private httpClient: HttpClient) { }
  ngOnInit() {
    this.httpClient.get('assets/header.csv', { responseType: 'text' }).subscribe(
      data => {
        this.myData = data.split("\n");
      }
    );
  }
  clicked(event) {
    console.log(event.srcElement.name);
    this.httpClient.get('assets/tableContent.csv', { responseType: 'text' }).subscribe(
      data => {
        this.myContent.push({event.srcElement.name: data.split(",")});
        let ab=this.myContent;
        console.log("------------>",ab);        
      }
    );
  }
}

Upvotes: 0

Related Questions