How do i convert uploaded csv into json object in angularjs - angularjs

var app = angular.module('myngCsv', [ngcsv]);
app.controller('ngcsvCtrl', function($scope,$csv) {
$scope.csv ={
content: null;
header: true,
headerVisible: true,
separator: ',',
separatorVisible: true,
result: null,
encoding: 'ISO-8859-1',
encodingVisible: true,
accept: ".csv"
};
});
This is what tried.
indeed.

You can write a function to convert CSV to JSON and pass your CSV object to it. All you need to do is to save the first row of CSV as headers (You can identify them by comma) and you can identify new entry by newline character \n
Go through the function I have written below.
function csvToJSON(csv, callback) {
var lines = csv.split("\n");
var result = [];
var headers = lines[0].split(",");
for (var i = 1; i < lines.length - 1; i++) {
var obj = {};
var currentline = lines[i].split(",");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
if (callback && (typeof callback === 'function')) {
return callback(result);
}
return result;
}

You can try using Papaparse looks very easy and elegant to use

Create fileReader directive:
<input type="file" data-file-reader-directive="fileContent" accept=".csv" />
Directive to get csv data from the file:
app.directive('fileReaderDirective', function() {
return {
restrict: "A",
scope: {
fileReaderDirective: "=",
},
link: function(scope, element) {
$(element).on('change', function(changeEvent) {
var files = changeEvent.target.files;
if (files.length) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
scope.$apply(function() {
scope.fileReaderDirective = contents;
});
};
r.readAsText(files[0]);
}
});
}
};
});
Create a factory to convert csv data to json data
app.factory('readFileData', function() {
return {
processData: function(csv_data) {
var record = csv_data.split(/\r\n|\n/);
var headers = record[0].split(',');
var lines = [];
var json = {};
for (var i = 0; i < record.length; i++) {
var data = record[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j = 0; j < headers.length; j++) {
tarr.push(data[j]);
}
lines.push(tarr);
}
}
for (var k = 0; k < lines.length; ++k){
json[k] = lines[k];
}
return json;
}
};
});
check out the working example : https://plnkr.co/edit/ml29G85knZpWWNdG8TeT?p=preview

Related

How can maintain the view in the bottom of the list when I add another element in my infinitescroll list ? angularjs

I have an issue I have a "chat" and when I add a new text in my infinite scroll container,
I go back to the top of the page, i'm not stuck to the bottom.
How can I maintain the page in the bottom of my page while people chat
my service
tabs.factory('chat', function ($http, $timeout, $q) {
return {
default: {
delay: 100
},
data: [],
dataScroll: [],
init: function (data) {
if (this.data.length == 0) {
for (var i = 0; i < data.length; i++) {
this.data[i] = data[i]
}
} else {
var tailleDataSaved = this.data.length
var dataAAjouter = data.slice(tailleDataSaved)
for (var i = 0; i < dataAAjouter.length; i++) {
this.data.push(dataAAjouter[i])
}
}
},
request: function (showAll) {
var self = this;
var deferred = $q.defer();
var index = this.dataScroll.length
var ndDataVisible = 7
var start = index;
var end = index + ndDataVisible - 1;
$timeout(function () {
if (!showAll) {
var item = []
if (start < end) {
for (var i = start; i < end; i++) {
console.log(start)
console.log(end)
console.log(self.data[i])
if (item = self.data[i]) {
self.dataScroll.push(item);
}
}
}
} else {
self.dataScroll = self.data
}
deferred.resolve(self.dataScroll);
}, 0);
return deferred.promise;
}
}
})
my js file
$scope.listChat= function () {
$scope.isActionLoaded = false;
$http.get(apiurl).then(function (response) {
chat.init(response.data)
$scope.isActionLoaded = true
})
}
$scope.listChatInfiniteScroll = function () {
$scope.isScrollDataLoaded = false
ticketListeActionScroll.request(false).then(function (response) {
$scope.actionsInfiniteScroll = response
$scope.isScrollDataLoaded = true
})
}
html file
<div ng-if="isActionLoaded" infinite-scroll='listChatInfiniteScroll ()' infinite-scroll-distance='1'>
<div ng-repeat="chat in actionsInfiniteScroll">
{{chat.text}}
</div>
</div>
Each time I add a new message it calls listChat

For-loop return array value

I'm trying to insert url for menu through mustache template. But just the first value is being returned for the array.
Or is this the return method wrong
var main_menu_link = ["main_dashboard.html", "#", "online_dashboard.html","index.html","#","#","#"];
var url = "";
var i;
var url_link="";
for(i = 0; i < main_menu_link.length; i++) {
url += main_menu_link[i];
return '' + text + '';
}
CodePen working here
The return statement has to be after the loop:
var main_menu_link = ["main_dashboard.html", "#", "online_dashboard.html","index.html","#","#","#"];
var url = "";
var i;
var url_link="";
for(i = 0; i < main_menu_link.length; i++) {
url += '' + text + '';
}
return url;
Correct template as below in-case it can be of use to someone else
var link_details = { "link_details" :[
{ main_menu: "Dashboard", main_menu_link: "dashboard.html" },
{ main_menu: "Analytics", main_menu_link: "#" },
{ main_menu: "System", main_menu_link: "system.html" }
]};
var template = "<ul>{{#link_details}}<li>{{main_menu}}</li>{{/link_details}}‌​</ul>";
var html = Mustache.to_html(template, link_details);
document.write(html)

Infdig in Custom groupBy

i recently needed some kinda customized repeater, which group data by their key, but not simply group them all together, so i read several references and things,... and at last i come up to copy
groupBy from this article which he seem to complete it at best, ...
http://sobrepere.com/blog/2014/10/14/creating-groupby-filter-angularjs/
And then i customized so it become like this:
the things my group by do... is:
Group Data Together Until It Reach Differences.
but the matter is that though it work, it still generate infdig, i know it's because the digest done call other one, but what i don't know is how to solve it in very easy and understandable manner, as i'm new to JavaScript...
app.filter('groupBy', function () {
var results = {};
return function (data, key) { //Data => My Objects Array - Key => Name Of Filtered Property
if (!(data && key)) return;
var result;
if (!this.$id) {
result = {};
} else {
var scopeId = this.$id;
if (!results[scopeId]) {
results[scopeId] = {};
this.$on("$destroy", function () {
delete results[scopeId];
});
}
result = results[scopeId];
}
for (var groupKey in result)
result[groupKey].splice(0, result[groupKey].length);
var grpKey = -1; //GroupKey
var lastUserId;
for (var i = 0; i < data.length; i++) {
if (!result[grpKey] || lastUserId && lastUserId != data[i][key]) // Ex.: result[data[0]["UserId"]]{ => return UserId
result[++ grpKey] = [];
result[grpKey].push(data[i]);
lastUserId = data[i][key];
}
var keys = Object.keys(result);
for (var k = 0; k < keys.length; k++) {
if (result[keys[k]].length === 0)
delete result[keys[k]];
}
return result;
};
});
In this url is working perfectly...
http://plnkr.co/edit/8jB4wSRtKfVmEsTGZtfV?p=preview
app.filter('groupBy', function ($timeout) {
return function (data, key) {
if (!key) return data;
var outputPropertyName = '__groupBy__' + key;
if(!data[outputPropertyName]){
var result = {};
for (var i=0;i<data.length;i++) {
if (!result[data[i][key]])
result[data[i][key]]=[];
result[data[i][key]].push(data[i]);
}
Object.defineProperty(result, 'length', {enumerable: false, value: Object.keys(result).length});
Object.defineProperty(data, outputPropertyName, {enumerable:false, configurable:true, writable: false, value:result});
$timeout(function(){delete data[outputPropertyName];},0,false);
}
return data[outputPropertyName];
};
});

AngularJS extend model

I had in my old project this bit of code for an API:
.factory('Api', ['$resource', 'apiUrl', function ($resource, api) {
var Api = $resource(api + ':path', {
path: '#path'
});
return Api;
}])
and then I had an Order model which extended this factory class like this:
.factory('Order', ['$filter', 'Api', function ($filter, api) {
var Order = api;
angular.extend(Order.prototype, {
getDescription: function () {
var rolls = 0,
cuts = 0,
skus = [],
lines = $filter('orderBy')(this.lines, 'sku');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
switch (line.type) {
case 0: // cut
cuts++;
break;
case 1: // roll
rolls++
break;
}
if (skus.indexOf(line.sku) == -1) {
skus.push(line.sku);
}
}
var description = '';
description += cuts > 0 ? cuts > 1 ? cuts + ' x cuts' : cuts + ' x cut' : '';
description += rolls > 0 && description.length > 0 ? ', ' : '';
description += rolls > 0 ? rolls > 1 ? rolls + ' x rolls' : rolls + ' x roll' : '';
description += skus.length == 1 ? ' of ' + skus[0] : '';
return description;
},
getStatus: function () {
var lines = this.lines,
status = lines[0].status;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (status !== line.status)
return 'Multiple';
}
return status;
},
getDeliveryDate: function () {
var lines = this.lines,
date = lines[0].dates.delivery;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (date !== line.dates.delivery)
return 'Multiple';
}
date = new Date(date);
return date;
},
getDispatchDate: function () {
var lines = this.lines,
date = lines[0].orderDate;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (date !== lines.orderDate)
return 'Multiple';
}
date = new Date(date);
return date;
}
});
return Order;
}]);
Now, I have recently changed my API factory to this:
// ---
// CONSTANTS.
// ---
.constant('apiUrl', 'http://localhost:54326/')
//.constant('apiUrl', 'http://localhost:81/')
// ---
// SERVICES.
// ---
.service('Api', ['$http', 'HttpHandler', 'apiUrl', function ($http, handler, apiUrl) {
// Private function to build our request
var buildRequest = function (url, method, data, params) {
var model = {
method: method,
url: apiUrl + url,
data: data,
params: params
};
return $http(model);
}
// GET
this.get = function (url, params) {
return handler.loadData(buildRequest(url, 'GET', null, params));
}
// POST
this.post = function (url, data) {
return handler.loadData(buildRequest(url, 'POST', data));
}
// PUT
this.put = function (url, data) {
return handler.loadData(buildRequest(url, 'PUT', data));
}
// DELETE
this.delete = function (url, data) {
return handler.loadData(buildRequest(url, 'DELETE', data));
}
}])
When I did this, my order model no longer works. I get an error stating:
Cannot read property '$$hashKey' of undefined
Is there a way I can get my Order model to use the new API factory? Specifically I want to attach functions each object returned by the API.

How to get the image dimension with angular-file-upload

I'm currently using the angular-file-upload directive, and I'm pretty much using the exact codes from the demo.
I need to add a step in there to test for the dimension of the image, and I am only currently able to do with via jQuery/javascript.
Just wondering if there's a "angular" way to check for the dimension of the image before it's being uploaded?
$scope.uploadImage = function($files) {
$scope.selectedFiles = [];
$scope.progress = [];
if ($scope.upload && $scope.upload.length > 0) {
for (var i = 0; i < $scope.upload.length; i++) {
if ($scope.upload[i] !== null) {
$scope.upload[i].abort();
}
}
}
$scope.upload = [];
$scope.uploadResult = [];
$scope.selectedFiles = $files;
$scope.dataUrls = [];
for ( var j = 0; j < $files.length; j++) {
var $file = $files[j];
if (/*$scope.fileReaderSupported && */$file.type.indexOf('image') > -1) {
var fileReader = new FileReader();
fileReader.readAsDataURL($files[j]);
var loadFile = function(fileReader, index) {
fileReader.onload = function(e) {
$timeout(function() {
$scope.dataUrls[index] = e.target.result;
//------Suggestions?-------//
$('#image-upload-landscape').on('load', function(){
console.log($(this).width());
});
//-------------------------//
});
};
}(fileReader, j);
}
$scope.progress[j] = -1;
if ($scope.uploadRightAway) {
$scope.start(j);
}
}
};
I think you can do it by:
var reader = new FileReader();
reader.onload = onLoadFile;
reader.readAsDataURL(filtItem._file);
function onLoadFile(event) {
var img = new Image();
img.src = event.target.result;
console.log(img.width, img.height)
}
This is the code snippet copied from https://github.com/nervgh/angular-file-upload/blob/master/examples/image-preview/directives.js.
I think this is more angularjs. However, you may need to modify it to fit your requirement.
Try this code
uploader.filters.push({
name: 'asyncFilter',
fn: function(item /*{File|FileLikeObject}*/ , options, deferred) {
setTimeout(deferred.resolve, 1e3);
var reader = new FileReader();
reader.onload = onLoadFile;
reader.readAsDataURL(item);
function onLoadFile(event) {
var img = new Image();
img.onload = function(scope) {
console.log(img.width,img.height);
}
img.src = event.target.result;
}
}
});

Resources