I'm trying to build a simple csv reader for our project. first i builded one in JS and it worked fine, but i have difficulties converting it to ts.
this is the simple html code:
<div id="dvImportSegments" class="fileupload">
<fieldset>
<legend>Upload your CSV File</legend>
<input type="file" name="File Upload" id="txtFileUpload" (change)="changeListener($event)" accept=".csv"/>
</fieldset>
</div>
and this is the typescript that run on it:
import {Component, ViewEncapsulation} from 'angular2/core';
import {Router} from 'angular2/router';
import {ContentService} from "../service/contentService";
import {RouteParams} from "angular2/router";
#Component({
selector: 'createCsv',
templateUrl: 'app/partials_html/createCsv.component.html',
encapsulation: ViewEncapsulation.None
})
export class CreateCsvComponent {
changeListener($event):void {
this.upload($event.target);
}
upload(inputValue:any):void {
var data = null;
var file:File = inputValue.files[0];
var reader:FileReader = new FileReader();
//reader.readAsText(file);
reader.onloadend = function (e) {
var csvData = reader.result;
data = $.csv.toArrays(csvData); //???
if (data && data.length > 0) {
alert('Imported -' + data.length + '- rows successfully!');
} else {
alert('No data to import!');
}
};
reader.onerror = function () {
alert('Unable to read ' + file);
};
}
//}
}
but i have some errors, data = $.csv.toArrays(csvData); //??? he cannot find the $ sign in there, how can i adress that?
Thanks in advance
he cannot find the $ sign in there
You are probably using https://github.com/evanplaice/jquery-csv
You need a TypeScript declaration file for JavaScript libraries that are not a part of your code base. A simple one vendor.d.ts:
declare var $:any;
Also you need to look at your module loader to make sure that the desired libraries are loaded before you code runs.
More
Some docs on declaration files and migrating : https://basarat.gitbooks.io/typescript/content/docs/types/migrating.html
Related
I have a code to read data from excel using Angular Typescript. Its working file till converted to JSON. But didn't fetch into HTML Page. Problem is in column name of Excelsheet.
Excel file column names are like (i) Autodesk Material Description (ii) Autodesk SAP Material Description
If I use in HTML {{pricedata.Autodesk Material Description}}, {{pricedata.Autodesk SAP Material Description}}. It gives me error.
So I converted that name into (i) Autodesk_Material_Description (ii) Autodesk_SAP_Material_Description IN EXCELSHEET and code too ({{pricedata.Autodesk_Material_Description}}, {{pricedata.Autodesk_SAP_Material_Description}}).
Now it's working fine. So, how to handle this problem ?
import { Component, HostListener } from '#angular/core';
import * as XLSX from 'xlsx';
#Component({
selector: 'app-importpricelist',
templateUrl: './importpricelist.component.html',
styleUrls: ['./importpricelist.component.css']
})
export class ImportpricelistComponent
{
ExcelData:any;
constructor(){
}
ReadExcel(event:any){
let file = event.target.files[0];
let fileReader = new FileReader();
fileReader.readAsBinaryString(file);
fileReader.onload = (e) => {
var workBook = XLSX.read(fileReader.result, {type:'binary'});
var SheetNames = workBook.SheetNames;
this.ExcelData = XLSX.utils.sheet_to_json(workBook.Sheets[SheetNames[0]]);
console.log(this.ExcelData);
}
}
}
Short story: I am making my own GIS (geographic information system) and want to be able to upload JSON files with geographical data. I do not however want to save files in a database, just in a list. Furthermore I'm using Context to parse data to the <MAP/> (leaflet) component.
My problem is that when pushing the JSON to the list it is not recogniezed as a JSON but as string. How can I solve this problem.
I am quite new to react so I am open for suggestions to solve it differently.
Here is my code
import React, {createContext, useState} from 'react';
import "../../App.css";
import data from '../../Layers/layer1.json'
import data1 from '../../Layers/layer2.json'
export const FileContext = createContext()
const layerList = []
function updateList(layer){
layerList.push(layer)
}
export const FileProvider = (props) => {
const [layer, setLayer] = useState(
layerList
)
return(
<FileContext.Provider value = {[layer, setLayer]}>
{props.children}
</FileContext.Provider>
);
}
// Create an object of formData
const onFileChange = e => {
const fileReader = new FileReader();
fileReader.readAsText(e.target.files[0], "UTF-8");
fileReader.onload = e => {
console.log(e.target.result);
updateList(e.target.result);
console.log(layerList)
};
//console.log(layerList)
}
function FileUpload() {
return (
<div>
<div id='fileupload'>
<input type="file" onChange={onFileChange} />
</div>
</div>
);
}
export default FileUpload;
And this is the Map component
import { Map, TileLayer, GeoJSON} from 'react-leaflet'
import "../App.css";
import data from '../Layers/layer1.json'
import { FileContext } from '../LandingPage/ToolbarComponents/FileUpload';
function MapOslo() {
const [layer, setLayer] = useContext(FileContext)
return (
<Map center={[59.93, 10.75]} zoom={4}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© OpenStreetMap contributors'
/>
<GeoJSON data={layer} style={['color','#006400']} />
</Map>
);
}
export default MapOslo;
To convert a String to JSON you can use JSON.parse(str)
var jsonStr = "{test: 'hi'}";
var json = JSON.parse(jsonStr);
So I think you have to implement parse here: updateList(JSON.parse(e.target.result));
I have started with vue and D3. I just want to show my csv data in the console but when I try to do it with D3 CSV function is not working at all. Appears an array of 16 HTML elements which are in index.html, would you mind helping me with this?
This is my project structure:
This is my component code:
<template>
</template>
<script>
import * as d3 from "d3";
import { csv } from 'd3';
export default {
name: 'mycomponent',
data() {
return{
dataset: [],
}
},
async mounted(){
const data = await d3.csv('./datasets/dataset.csv')
this.$data.$dataset = Object.freeze(data)
console.log(data);
}
}
</script>
This is home:
<template>
<mycomponent></mycomponent>
</template>
<script>
import mycomponent from '#/components/mycomponent.vue'
export default {
name: 'Home',
components: {
mycomponent,
},
}
</script>
And this is what I get in console:
The d3.csv function will execute at runtime not compile-time so you have to put your csv file in public directory then use it as usual public files.
let data = await d3.csv("/datasets/dataset.csv")
Or if you want to load your csv file at compile-time you can import it as string and use d3.csvParse instead.
import dataset from '#/datasets/dataset.csv'
let data = d3.csvParse(dataset);
I would prefer the first method, in the second method your csv file might cause your script file too big.
Example
I have an HTML input element that when a user enters a ? it opens a MatDialog window. I need to still pass the ? value to the openLookupDialog method that opens the MatDialog but I want to hide/mask the ? from the user.
Here's my code example:
<input matInput aria-label="State"
[formControl]="countryLookupModalDialogForm"
(keyup)="openLookupDialog($event)"
class="lookup-input" [ngModel]="countryModalDialogLookupInput">
openLookupDialog(event: any): void {
if (event.target.value !== '?') {
return;
}
const dialogRef = this.dialog.open(LookupdialogComponent, {width: '450px'});
dialogRef.componentInstance.rowSelected.subscribe(result => {
this.doSetResult(result);
});
I have had a play around in the stackBlitz you created for me, and thank you for doing that, I hope what I have come up with is able to help you find a solution that best use your use case.
import { Component } from '#angular/core';
import { FormControl, FormGroup, FormBuilder } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
countryLookupModalDialogForm = new FormControl();
openLookupDialog(event: any): void {
/******/
// Below is a possible solution if you want to use '?' as a forbidden char
/******/
const str = event.target.value;
const regexp = /[?]/gi; // really good site to explore this further: https://regexr.com/
const found = str.match(regexp);
console.log(found);
if (found != null) {
console.log(' Do what you will :)');
}
/******/
// Below is a possible solution if your only worried about the first character
/******/
if (event.target.value !== '?') {
return;
}
event.target.value = '';
setTimeout(() => {
window.alert('MatDialog Opened Successfully!')
},100); // Give the value enough time to change before alert box activates (0.1 second)
}
}
I have create a page with different input elements with file upload. While saving the form with multiple files along with form input elements using angular 6, the file object is empty {} in console an http service in network tab.
Here is my code:
onFileChanged(event) {
this.selectedFiles = event.target.files;
const uploadData = new FormData();
uploadData.append('myFile', this.selectedFiles, this.selectedFiles[0].name);
this.createFormData.attachment = uploadData;
};
Can anyone provide a sample to help me?
This is example of upload method in service. Pass files and input values from component to service, create formData, loop on files and append each file to formData and same with input values.
upload(files, inputs) {
let formData = new FormData();
files.map((file) => {
formData.append('file', file);
});
inputs.map((input) => {
formData.append(`${input.name}`, input.value);
});
return this.http.post(`some/api/upload`, formData)
.pipe(map((res) => res.data));
}
With this example your request should contain all array of files and inputs, also if you need some special header add it after formData in post method (in my case i handle headers in interceptor).
upload(files, inputs) {
let formData = new FormData();
files.map((file) => {
formData.append('file', file);
});
inputs.map((input) => {
formData.append(`${input.name}`, input.value);
});
const headers = new HttpHeaders({
'Accept': 'application/json'
});
const options = { headers: headers };
return this.http.post(`some/api/upload`, formData, options)
.pipe(map((res) => res.data));
}
Have a look at following example with npm's ng2-file-upload (in this case with a fontAwsome-icon).
myFileUploadForm.component.html:
<!-- file upload -->
<input #fileToUpload type="file" style="display:none;" ng2FileSelect (change)="onFileChanged($event)" [uploader]="uploader"
name="customerFile" id="customerFile" class="customerFile" />
<a href="javascript:document.getElementById('customerFile').click();">
<fa class="ql-upload" *ngIf="buttonDeaktivieren" [title]="'Upload'" [name]="'upload'" [size]="0.9" [border]=false></fa>
</a>
myFileUploadForm.component.ts (I'll ommit the obvious parts with ..):
import { Component, OnInit, ViewChild, OnDestroy, TemplateRef } from '#angular/core';
import { Subscription, Observable } from '../../../../../node_modules/rxjs';
....
...
import { FileUploader } from 'ng2-file-upload';
#Component({
....
...
..
})
export class myFileUploadFormComponent implements OnInit, OnDestroy {
public uploader: FileUploader = new FileUploader({ url:
'http://localhost:3000/files/uploadFile/', itemAlias: 'customerFile' });
filesArray = [];
constructor(
...
..
private http: Http
) { }
ngOnInit() {
....
...
..
}
// INFO: Function for opening confirm modal when deleting file
openDeleteFileModal(file) {
const initialState = {
file: file
};
this.deleteFileModalRef = this.modalService.show(ConfirmFileDeletionComponent, {
initialState, class: 'modal-md modal-dialog-centered' });
}
// INFO: Handy helper for assigning appropriate file-icon according to extension
getFilesIcon(file) {
if (file === 'docx') {
return 'file-word-o';
} else if (file === 'jpeg' || file === 'jpg' || file === 'png') {
return 'image';
} else if (file === 'pdf') {
return 'file-pdf-o';
} else if (file === 'xlsx' || file === 'xls') {
return 'file-excel-o';
} else if (file === 'pptx') {
return 'file-powerpoint-o';
} else if (file === 'zip') {
return 'file-archive-o';
} else {
return 'file';
}
}
/* INFO : service for downloading the uploaded file */
downloadFile(filename) {
this.fileDataService.downloadFile(filename);
}
onFileChanged(event) {
this.uploader.onBuildItemForm = (fileItem: any, form: any) => {
form.append('id', this.customer.id);
form.append('customername', this.customer.customername);
};
this.uploader.uploadAll();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Obviously this is my implementation suited to my needs (uploaded files are related to a certain customer and are displayed with icons according to extension and listed for future download or deletion as well), but I'm sure you can get it done by adjusting the code to your needs and write the relevant services. Have a nice one weekend ;)