I want to read some data from a CSV file and create multiple canvases that contains the data from my CSV. I want each line of the CSV to have it's own canvas.
This is the code:
<!DOCTYPE html>
<html>
<head>
<title>BaGr (Badge Generator)</title>
</head>
<body>
<h3>Create</h3>
<div id="output">
<script>
const output = document.getElementById("output");
let objects = [];
function init() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function (){
if(this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
//parsing objects, so reusable
objects = generateObjects(this.responseText);
//once objects are parsed generate view
generateView();
}
}
xhttp.open("GET", "test.txt", true);
xhttp.send();
}
generateObjects = (responseText) => {
const lines = responseText.split("\n");
return lines.map(lineRaw=>{
const line = lineRaw.split(',');
if(line.length !== 4){
console.warn("Line error.");
return undefined;
}
return {name: line[0], surname: line[1], sex: line[2], role: line[3]};
});
}
generateView = () => {
output.innerHTML = objects.map(object=>generateCanvas(object).outerHTML).join("");
}
generateCanvas = (line) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
let pos = 230;
for(let key in line){
if(line.hasOwnProperty(key)){
context.fillText(`${key.toUpperCase()}: `, 30, pos);
context.fillText(line[key], 150, pos);
pos += 20;
}
}
return canvas;
}
window.onload = init;
</script>
</div>
</body>
</html>
Still not working properly. When i click on inspect i see that the code has the canvases generated but they don't appear on my page.
Here is a working version of what you're looking for. If you have any questions let me know.
const output = document.getElementById("output");
let objects = [];
function init() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//parsing objects, so reusable
objects = generateObjects(this.responseText);
//once objects are parsed generate view
generateView();
}
}
xhttp.open("GET", "test.txt", true);
xhttp.send();
}
generateObjects = (responseText) => {
const lines = responseText.split("\n");
return lines.map(lineRaw => {
const line = lineRaw.split(',');
if (line.length !== 4) {
console.warn("Line error.");
return undefined;
}
return {
name: line[0],
surname: line[1],
sex: line[2],
role: line[3]
};
});
}
generateView = () => {
objects.forEach(object => generateCanvas(object))
}
generateCanvas = (line) => {
const canvas = document.createElement("canvas");
output.appendChild(canvas);
const context = canvas.getContext("2d");
let pos = 50;
for (let key in line) {
if (line.hasOwnProperty(key)) {
context.fillText(`${key.toUpperCase()}:`, 30, pos);
context.fillText(line[key], 150, pos);
pos += 20;
}
}
}
Working example with provided data
const output = document.getElementById("output");
let objects = [{
"name": "Popescu",
"surname": "Bogdan",
"sex": "masculin",
"role": "student\r"
}, {
"name": "Prelipcean",
"surname": "Radu",
"sex": "masculin",
"role": "avocat\r"
}, {
"name": "Antonie",
"surname": "Ioana",
"sex": "feminin",
"role": "profesor\r"
}, {
"name": "Arhire",
"surname": "Raluca",
"sex": "feminin",
"role": "asistenta\r"
}, {
"name": "Panaite",
"surname": "Alexandru",
"sex": "masculin",
"role": "contabil\r"
}, {
"name": "Bodnar",
"surname": "Ioana",
"sex": "feminin",
"role": "vizitator"
}];
generateView = () => {
objects.forEach(object => generateCanvas(object))
}
generateCanvas = (line) => {
const canvas = document.createElement("canvas");
output.appendChild(canvas);
const context = canvas.getContext("2d");
let pos = 50;
for (let key in line) {
if (line.hasOwnProperty(key)) {
context.fillText(`${key.toUpperCase()}:`, 30, pos);
context.fillText(line[key], 150, pos);
pos += 20;
}
}
}
generateView();
<div id="output"></div>
Related
I have a json file like below (test.json). I am unsuccessfully trying to parse the test array and remove duplicates of any "name" below
{
"test": [{
"name": "jeb",
"occupation": "teacher"
},
{
"name": "jeb",
"occupation": "writer"
},
{
"name": "bob",
"occupation": "skydiver"
}
]
}
So far, my code is the following:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
var i;
var test= myObj.test.length;
for (i=0; i<=myObj.test.length; i++) {
var name = myObj.test[i].name;
var occupation = myObj.test[i].occupation;
console.log(name + " and " + occupation)
}
}
}
xmlhttp.open("GET", "test.json", true);
xmlhttp.send();
and it prints out:
jeb and teacher
jeb and writer
bob and skydiver
I would like the end result to be be:
jeb and teacher, writer
bob and skydiver
Any help is appreciated. Thank you!
It would probably be best to reduce into an object indexed by name, whose value is an array of occupations, and then once the object is created, you can iterate over it and print the occupations of each name:
const obj = {
"test": [{
"name": "jeb",
"occupation": "teacher"
},{
"name": "jeb",
"occupation": "writer"
},{
"name": "bob",
"occupation": "skydiver"
}]
};
const namesByOccupation = obj.test.reduce((a, { name, occupation }) => {
if (!a[name]) a[name] = [];
a[name].push(occupation);
return a;
}, {});
Object.entries(namesByOccupation).forEach(([name, occupations]) => {
console.log(name + ' and ' + occupations.join(', '));
});
I am new to js and jasmine
I am trying to right a jasmine test case for my method.
But I am facing an error: TypeError: Cannot read property '0' of undefined.
I tried various ways of passing array into my method sports but still I am getting same error. Can you guys tell me how to fix it?
The test
it('Read player hiking', (done) => {
let callFirstTime : boolean = true;
let url=
spyOn(swimming.playerhikings.movieService,'getResponse').and.
callFake(() => {
if(callFirstTime){
callFirstTime = false; // Invoked by detectChanges()
return Observable.of([{
"hikingId": "100",
"hikingName": "http://localhost:3000/assets/js/actualairings.json",
"hikingType": "TITLE",
"hikingData": "YWZjYXJlZ2Vyamh2dmFyZWdoYnZi",
"notes": "",
"notesId": "100",
"elfDocID": "100",
"url": "http://localhost:3000/upload",
"date": "06/27/2017",
"addedByName": "Kamal",
"userID": "206509786",
"operationType": "create"
}, {
"hikingId": "101",
"hikingName": "uploadTest4.txt",
"hikingType": "TITLE",
"hikingData": "Manish",
"notes": "",
"notesId": "101",
"elfDocID": "101",
"url": "http://localhost:3000/upload",
"date": "06/27/2017",
"addedByName": "Kamal",
"userID": "206509786",
"operationType": "create"
}]
);
}
});
//const args = ['p0', 'p1', 'p2'];
//call_me.apply(this, args);
var fruits = ['Apple', 'Banana'];
var fruits1 = {"test": "1"};
//console.log("swimming.playerhikings---->" +
// JSON.stringify(swimming.playerhikings.sports.apply(this, args)));
//spyOn(swimming.playerhikings.gridkendo,'enableSavehiking').and.returnValue(null);
//swimming.playerhikings.fileSelect = "text.txt";
//swimming.playerhikings.sports(fruits[0]);
swimming.playerhikings.sports(fruits1.test);
//swimming.playerhikings.coffee( {0: File, length: 1});
//console.log("swimming.playerhikings._dataSource._data.length---->" + swimming.playerhikings._dataSource._data.length);
fixture.whenStable().then(() => {
done();
//expect(swimming.playerhikings._dataSource._data.length).toEqual(3);
});
});
The code
sports(inputValue: any): void {
var that = this;
var file: File = inputValue.files[0];
var myReader: FileReader = new FileReader();
myReader.onloadend = (e) => {
this.encodeBase64 = myReader.result;
that.fileSelect = $("#attachhikingBrowseBtn").val().replace(/^.*\\/, "");
if (that.fileSelect == '') {
that.dragDrop = that.clearBtn;
} else {
that.dragDrop = "";
that.dragDrop = that.fileSelect;
}
}
$('.addELFhikingForm').show();
if (inputValue.files.length > 0) {
var fileSize = 0;
fileSize = inputValue.files[0].size / 1048576; //size in mb
if (fileSize > 5) {
alert("The hiking size exceeds the max limit of 5 MB");
//confirm("The hiking size exceeds the max limit of 5 MB");
}
myReader.readAsDataURL(file);
}
}
Here you have exactly what error message tells you: getting property '0' of undefined:
var fruits1 = {"test": "1"};
swimming.playerhikings.sports(fruits1.test);
And:
sports(inputValue: any): void {
var that = this;
var file: File = inputValue.files[0];
^^^^^^ undefined
}
No JQuery please. Only plain Javascript.
I have a particular JSON as this: data.json ->
{
"items": [
{
"name": "primAppName",
"title": "sample 1",
"author": "author 1"},
{
"name": "primAppName",
"title": "sample 2",
"author": "author 2"},
{
"name": "primAppName",
"title": "sample 3",
"author": "author 3"},
{
"name": "secAppName",
"title": "sample 4",
"author": "author 4"},
{
"name": "secAppName",
"title": "sample 5",
"author": "author 5"}
]
}
In Javascript what I am trying to do is, if the JSON key - "name" has value with substring "primApp" then I want to append "author" value to "witDetails" span and if the value has substring "secApp" then I want to append "author" value to "eanDetails" span.
Here is a plunker with full code. (My code contains a couple of files. That is why added to plunkr).
Desired Output :
loadFunctionJSON = function() {
//
// var data = JSON.parse(data);
var div = document.getElementsByClassName('functionJSONList')[0];
var witSpan = document.getElementById("WITDetails");
var eanSpan = document.getElementById("EANDetails");
$http('data.json').get().then(function(res) {
if (res) {
var data = res.items;
for (var event in data) {
var dataCopy = data[event];
for (var key in dataCopy) {
if (key.match(/name|value/)) {
if (key == "name" && dataCopy[key].indexOf("secApp") !== -1) {
var para = document.createElement("P"); // Create a <p> element
var t = document.createTextNode(dataCopy[key]); // Create a text node
para.appendChild(t); // Append the text to <p>
witSpan.appendChild(para); // Append <p> to <body>
}
// console.log('key : ' + key + ':: value : ' + dataCopy[key]);
}
}
}
}
});
};
/********* --AJAX Service-- ****************/
function $http(url) {
// A small example of object
var core = {
// Method that performs the ajax request
ajax: function(method, url, args) {
// Creating a promise
var promise = new Promise(function(resolve, reject) {
// Instantiates the XMLHttpRequest
var client = new XMLHttpRequest();
var uri = url;
if (args && (method === 'PUT')) {
uri += '?';
var argcount = 0;
for (var key in args) {
if (args.hasOwnProperty(key)) {
if (argcount++) {
uri += '&';
}
uri += encodeURIComponent(key) + '=' + encodeURIComponent(args[key]);
}
}
}
client.open(method, uri);
if (args && args.headers) {
var keys = Object.keys(args.headers);
for (var i = 0; i < keys.length; i++) {
client.setRequestHeader(keys[i], args.headers[keys[i]]);
}
}
if (args && args.data) {
client.send(JSON.stringify(args.data));
} else {
client.send();
}
client.onload = function() {
if (this.status >= 200 && this.status < 300) {
// Performs the function "resolve" when this.status is equal to 2xx
this.response ? resolve(JSON.parse(this.response)) : resolve(this);
} else {
// Performs the function "reject" when this.status is different than 2xx
var data = {};
try {
data = JSON.parse(this.responseText);
} catch (e) {
data = this.statusText;
}
if (data.error && data.error.message && data.error.message == "Invalid bearer token") {
BotUI.sessionOutOverlay();
} else {
reject(data);
}
}
};
client.onerror = function() {
reject(this.statusText);
};
});
// Return the promise
return promise;
},
put: function(method, url, args) {
var promise = new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open(args.method, url, true);
if (args && args.headers) {
var keys = Object.keys(args.headers);
for (var i = 0; i < keys.length; i++) {
request.setRequestHeader(keys[i], args.headers[keys[i]]);
}
}
request.onreadystatechange = function() {
if (request.status && request.readyState != 2) {
if (request.readyState == 4 && request.status == 201) {
return resolve({
headers: request.getAllResponseHeaders(),
data: JSON.parse(request.responseText)
});
} else if (200 == request.status && request.readyState == 4) {
if (!!request.responseText) {
if ((request.responseText).charAt(0) !== '<') {
resolve({
data: {
status: request.status,
response: JSON.parse(request.responseText)
}
});
} else {
return reject(request.responseText);
}
} else {
resolve({
data: {
status: request.status
}
});
}
} else {
if (request.readyState == 4 && request.status != 201) return reject(request.responseText);
}
}
};
if (args.isImage) {
request.send(args.data);
} else {
request.send(JSON.stringify(args.data));
}
});
return promise;
}
};
// Adapter pattern
return {
'get': function(args) {
return core.ajax('GET', url, args);
},
'post': function(args) {
return core.ajax('POST', url, args);
},
'put': function(args) {
return core.put('PUT', url, args);
},
'delete': function(args) {
return core.ajax('DELETE', url, args);
}
};
}
/* Styles go here */
.functionRightCol {
float: right;
width: 50%;
}
.functionLeftCol {
float: left;
width: 50%;
}
.WITEntityName {
text-transform: uppercase;
text-align: center;
}
.BOTPropertyName {
text-transform: uppercase;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<script type="text/javascript" src="data.json"></script>
<script src="api.js"></script>
</head>
<body onload="loadFunctionJSON()">
<div class="functionJSONList">
<div name="functionWIT" id="functionWIT" class="functionWIT"></div>
<span id="WITDetails" style='text-align:left'>WIT</span>
<div name="functionEAN" id="functionEAN" class="functionEAN"></div>
<span id="EANDetails" style='text-align:left'>ENTITY APP NAME</span>
<div class="functionResults">
<span class="WITEntityName functionLeftCol">WIT Entity Name</span>
<span class="BOTPropertyName functionRightCol">BOT Property Name</span>
</div>
</div>
</body>
</html>
You can loop inside json using forEach.
hope this will help.
var data = {
"items": [
{
"name": "primAppName",
"title": "sample 1",
"author": "author 1"},
{
"name": "primAppName",
"title": "sample 2",
"author": "author 2"},
{
"name": "primAppName",
"title": "sample 3",
"author": "author 3"},
{
"name": "secAppName",
"title": "sample 4",
"author": "author 4"},
{
"name": "secAppName",
"title": "sample 5",
"author": "author 5"}
]
};
var a = document.getElementById('a');
var b = document.getElementById('b');
data.items.forEach(function(item){
if(item.name.indexOf("primApp") >=0 ){
a.innerHTML = a.innerHTML + item.author +" ";
}else if(item.name.indexOf("secApp") >=0 ){
b.innerHTML = b.innerHTML + item.author +" ";
}
});
<span id="a"></span>
<br/><br/>
<span id="b"></span>
I have this JSON:
var person = {"id": "1", "name": "Michel"}
How would I return "1" when "Michel" is selected.
I have tried:
for (value in person) {
if (person.hasOwnProperty(value)) {
console.log(value+ " = " + person[value]);
}
}
You mean like this?
var person = [{"id": "1", "name": "Michel"}];
for(index=0;index<person.length;index++) {
if(person[index].name == 'Michel') {
console.log(person[index].id);
}
}
Another Way
var person = [{"id": "1", "name": "Michel"}];
var string = 'Michel';
function searchArray(str) {
var id = '';
for(index=0; index<person.length; index++) {
if(person[index].name == str) {
id = person[index].id;
}
}
return id;
}
var result_id = searchArray(string);
I have an issue about checking for an existing product in knockoutjs.
The problem is: if the product exists in Cart Line, the product quantity will increase, if not, it will be added to Cart
This is code:
var CartLine = function (productid,productName, price, quantity) {
var self = this;
self.resultId = ko.observable(productid);
self.resultProduct = ko.observable(productName);
self.resultPrice = ko.observable(price);
self.resultQuantity = ko.observable(quantity || 1);
self.subtotal = ko.computed(function () {
return self.resultPrice() * self.resultQuantity();
});
};
$('#addProduct').click(function (line) {
var context = ko.contextFor(this);
var existing = self.find(line.resultId);
var lines = self.lines();
if (existing) {
existing.resultQuantity = existing.resultQuantity() + context.$data.Quantity();
}else{
existing = new CartLine(self.product().productid, self.product().name, self.product().price, context.$data.Quantity());
self.lines.push(existing);
}
return existing;
});
self.find = function (productid) {
return ko.utils.arrayFirst(self.lines(), function (line) {
return line.resultId === productid;
});
};
This is the full code: http://jsfiddle.net/pf9hd3Lg/2/
There are a number of errors with the code you have listed above. The below should work for the scenario you described. I have tried to comment my changes in the code below.
var CartLine = function (productid,productName, price, quantity) {
var self = this;
self.resultId = ko.observable(productid);
self.resultProduct = ko.observable(productName);
self.resultPrice = ko.observable(price);
self.resultQuantity = ko.observable(quantity || 1);
self.subtotal = ko.computed(function () {
return self.resultPrice() * self.resultQuantity();
});
};
var Cart = function() {
var self = this;
self.products = ko.observableArray([{
"productid": "1",
"name": "CAPUCINO ",
"price": 170
},
{
"productid": "2",
"name": "Sữa bò tươi",
"price": 140
}
,
{
"productid": "3",
"name": "Phô mai mặn",
"price": 170
}, {
"productid": "4",
"name": "Bơ đậu phộng ",
"price": 150
},
{
"productid": "5",
"name": "Bạc Hà",
"price": 160
},
{
"productid": "6",
"name": "Dâu Tây",
"price": 160
}
]);
self.product = ko.observable("");
self.Quantity = ko.observable(1).extend({ numeric: 0 });
self.price = ko.observable();
self.productid = ko.observable("");
self.lines = ko.observableArray();
self.grandTotal = ko.pureComputed(function () {
var total = 0;
$(self.lines()).each(function (index, line) { total += line.subtotal() })
return total;
});
$('#addProduct').click(function (line) {
var context = ko.contextFor(this);
var existing = self.find();
var lines = self.lines();
if (existing) {
//existing.resultQuantity is also an observable and should be set this way and not with the = operator
existing.resultQuantity(existing.resultQuantity() + context.$data.Quantity());
}else{
existing = new CartLine(self.product().productid, self.product().name, self.product().price, context.$data.Quantity());
self.lines.push(existing);
}
return existing;
});
self.removeProduct = function (line,event) {
self.lines.remove(line);
};
self.find = function () {
return ko.utils.arrayFirst(self.lines(), function (line) {
//resultId is an observable
//self.product().productid is what you are interested in, no need to pass it into the function
return line.resultId() === self.product().productid;
});
};
}
ko.applyBindings(new Cart());