0

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.

2
  • What is the reason to split headers and data in to 2 files ? Commented May 27, 2020 at 7:08
  • @SupunDeSilva Thanks for the comment. Actually Header will comes from 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. Commented May 27, 2020 at 7:12

3 Answers 3

1

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>
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for the answer, You have given good approach, But I want to show data after click on particular heading of table. I don't want to load all data from tablecontent.csv. Suppose If I will click on myaccess the only myaccess data will come, If myaccess is not exist in tablecontent.csv the load should not populate.Can you update the answer, It will great help for me, Thanksss
Also a stackblitz verrsion stackblitz.com/edit/angular-ivy-zuncs7
Greate answer. Thanks
With your support, I achieved most of the functionality. I posted one more question. If you don't mind. Could you check.stackoverflow.com/questions/62041235/…
sure will do. Gimme 5
0
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);        
      }
    );
  }
}

10 Comments

Thanks for the comment. Table heading will comes from 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.
updated the solution, is it what you are looking for?
It is showing error on line this.myContent.push({event.srcElement.name: data.split(",")});
you changed myContent to array like i did?
core.js:6228 ERROR TypeError: Cannot read property 'push' of undefined
|
0

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

2 Comments

Thanks for the comment. Column length will never fix
Great give me 5 min will update my answer according to it.

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.