Making pdf files from each array's object - javascript

I am trying to create pdf file from each object in an array.
[
{
name: jack,
age: 20,
},
{
name: daniel,
age: 22,
}
];
first I try to catch each object.
var proceed = 0;
arrayObj.forEach((tasks, index) => {
if (index === proceed) {
tasks.forEach(task => {
$(this).tableRow(task)
})
$(this).singlePdf()
}
proceed++
})
dynamic table
$.fn.tableRow = function(task){
var row = "<tr><td"+task.name+"</td><td>"+task.age+"</td></tr>";
$("tbody").append(row);
};
pdf
$.fn.singlePdf = function(){
html2canvas(document.getElementById('a4'), {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var docDefinition = {
content: [{
image: data,
width: 500
}]
};
pdfMake.createPdf(docDefinition).download("table.pdf");
}
});
}
the problem here. when I run it, I am creating multiple pdf file, but it's putting all objects to each pdf...
this part of code not running as I expected.
if (index === proceed) {
tasks.forEach(task => {
$(this).tableRow(task)
})
$(this).singlePdf()
}
proceed++
How can I fix this problem?

Related

how to merge arrays from 2 different arrays

this is an image from the API that returns the test results before and after each other.
Initially when the user has not entered the test result, the array result = null, After the user enters, the array will have the same result as the image below:
my problem is after user input test, and then we update field result_template can be add or remove subjects so how do i merge subjects if use edit again result_template,
If there are new subjects but no scores are available, the default is set = 0
You can watch the video for better understanding: link
desired result: image
here is my code:
const { data } = await this.$store.dispatch(
`${UserGeneral.STORE_ADMIN_USER_KEY}/getDetailSchoolResults`,
this.$route.params.id
);
const formData = data.data;
if (formData.result) {
const listResultTemplate = formData.result.result.map((item) => {
let data = {
title: item.title,
subjects: [],
files: [],
};
item.files.forEach((file) => {
data.files.push(file);
});
item.subjects.forEach((subject) => {
data.subjects.push({
name: subject.name,
scores: {
total_score: subject.scores.total_score,
medium_score: subject.scores.medium_score,
private_score: subject.scores.private_score,
},
});
});
return data;
});
this.result = listResultTemplate;
} else {
const listResultTemplate = formData.result_template.result_template.map(
(item) => {
let data = {
title: item.title,
subjects: [],
files: [],
};
item.subjects.forEach((subject) => {
data.subjects.push({
name: subject,
scores: {
total_score: 0,
medium_score: 0,
private_score: 0,
},
});
});
return data;
}
);
this.result = listResultTemplate;
}
thanks for your help !

Keep LocalStorage after refreshing page

Currently, I enter data, it stores in the local storage and displays it accordingly. Here is the code for that flow:
Creating/Setting Data (in the create.js file)
let orders = [];
document.onreadystatechange = function () {
if (document.readyState === 'interactive') renderApp();
function renderApp() {
var onInit = app.initialized();
onInit.then(getClient).catch(handleErr);
function getClient(_client) {
window.client = _client;
//client.events.on('app.activated', onAppActivate1);
onAppActivate1();
}
}
};
function onAppActivate1() {
//intialize an array that will have all the keys user puts in
console.log('got here');
$("#btnCreateOrder").click(function () {
//orders = localStorage.getItem('orderlist');
let order = {
id: Date.now(),
order: document.getElementById('order').value,
name: document.getElementById('inputName').value,
date: document.getElementById('inputDate').value,
status: document.getElementById('inputStatus').value
}
orders.push(order);
if (!localStorage.getItem('orderlist') || JSON.parse(localStorage.getItem('orderlist')).length === 0) {
$window.localStorage.setItem('orderlist', JSON.stringify($scope.initData));
}
//localStorage.setItem('orderlist', JSON.stringify(orders));
client.instance.send({
message: {
orders: orders
}
});
client.instance.close();
});
}
function handleErr(err) {
console.log('Error Occuered', err);
}
Receiving/Displaying data (app.js)
function onAppActivate() {
//var displayID = new Array();
console.log("Hi!! We are in the app!");
client.instance.resize({ height: "350px" });
client.instance.receive(function (event) {
var data = event.helper.getData();
console.log("data is", data);
for (let i = 0; i < data.message.orders.length; ++i) {
console.log(data.message.orders.length);
const orderList = data.message.orders[i];
console.log("orderlist is ", orderList);
var order = document.createElement("div");
order.innerHTML = `<br/> Order#: ${orderList.order}<br/> Name: ${orderList.name}<br/>
Date: ${orderList.date} <br/> Status: ${orderList.status}`;
order.style.borderBottom = "1px solid black"
document.getElementById('orderhistory').appendChild(order);
}
})
when i refresh the app, my data stays but when i reload the browser, the data gets reset but I want the data to stay even if i reload the browser and keep appending to it

Recursive function only returning first result

I'm trying to implement a file upload feature using native DnD and the browser API.
I have to functions like so:
export function buildFileTree(allObjects) {
let fileTree = {}
allObjects.forEach((item, index) => {
traverseFileTree(fileTree, null, item)
})
return fileTree
}
export function traverseFileTree(fileTree, parent = null, item) {
let parentId = !!parent ? fileTree[parent].id : parent
if (item.isFile) {
item.file(file => {
fileTree[item.fullPath] = {
id: uuidv4(),
name: item.name,
parent_id: parentId,
file: item
}
})
}
if (item.isDirectory) {
fileTree[item.fullPath] = {
id: uuidv4(),
name: item.name,
is_directory: true,
parent_id: parentId,
file: null
}
let dirReader = item.createReader()
dirReader.readEntries(entries => {
entries.forEach((entry, index) => {
traverseFileTree(fileTree, item.fullPath, entry)
})
})
}
}
Which I use like so, and I'm getting very weird results, when I console.log the object, it shows the correct data, but when I try to stringify it, access any other attributes, or iterate over it; it's only showing the first result.
const handleUploadDrop = (files) => {
const finalFiles = buildFileTree(files)
console.log(finalFiles) // This shows the correct data
console.log(JSON.stringify(finalFiles)) // This only shows 1 item!!!
console.log(Object.keys(finalFiles).length) // This prints 1
}
I'm very confused by this and any help would be greatly appreciated.

Matching a string to one of many patterns and extracting data

I have a problem I want to solve with RegEx, or any other method if there is a better one. I've tried several ways to achieve the goal, but nothing really worked.
I have an array with endpoints:
const endpoints = [
{
id: 1,
url: "/api/items/:itemId"
},
{
id: 2,
url: "/api/users/:userName/delete"
},
{
id: 3,
url: "/api/users/:userName/edit"
}
];
And a request URL:
const url = "/api/users/max/edit";
Now what I want is to have a function which acts like this:
const rewrite = (url, endpoints) => {
// What is the best way to achieve the following return value:
return {
endpointId: 3,
values: {
userName: "max"
}
};
};
Explanation: The function should find the appropriate endpoint for the url. All parts of the endpoint url which start with a colon are not static, but should rather be replaced with values from the request url. In this case :userName should be replaced with max.
I've been in web development for some time now, but to be honest I've almost no clue how to solve such a problem.
const rewrite = (url, endpoints) => {
var doubledArray = Array.prototype.map.call(endpoints, function(el) {
return {
id: el.id,
url: el.url.split('/')
};
});
var parts = url.split('/');
var i = 0;
parts.forEach(function(element) {
doubledArray = doubledArray.filter(el => (element == el.url[i] || el.url[i].startsWith(':')));
i++;
});
return {
endpointId: doubledArray[0].id,
values: {
[`${doubledArray[0].url.filter(el => el.startsWith(':'))[0].substring(1)}`]: parts[doubledArray[0].url.findIndex(function (el) { return el.startsWith(':'); } )],
}
};
};
You can go through the endpoints making each .url into a RegExp to test the url against.
When a matching one is found, it is just a matter of extracting the needed part and making up an Object with the property name:
<script>
const myEndpoints = [
{
id: 1,
url: "/api/items/:itemId"
},
{
id: 2,
url: "/api/users/:userName/delete"
},
{
id: 3,
url: "/api/users/:userName/edit"
}
];
const myUrl = "/api/users/nermal/edit";
const rewrite = (url, endpoints) => {
for (let i = 0; i < endpoints.length; i++) {
var rep = new RegExp(":(\\w+)", "m");
var propName = rep.exec(endpoints[i].url);
var reu = new RegExp(endpoints[i].url.replace(propName[0], "(.*)"));
var a = reu.exec(url);
if (a !== null) {
var x = new Object;
x["endpointId"] = endpoints[i].id;
var y = new Object;
y[propName[1]] = a[1];
x["values"] = y;
return x;
}
}
return null;
};
var q = rewrite(myUrl, myEndpoints);
console.log(q);
console.log(q.values);
</script>
Outputs:
Object { endpointId: 3, values: {…} }
Object { userName: "nermal" }

KnockOutJS trigger parent function on child subscribe

I am currently trying to learn KnockOutJS. I thought it would be a great idea to create a simple task-list application.
I do not want to write a long text here, let's dive into my problem. I appreciate all kind of help - I am new to KnockOutJS tho!
The tasks are declared as followed:
var Task = function (data) {
var self = this;
self.name = ko.observable(data.name);
self.status = ko.observable(data.status);
self.priority = ko.observable(data.priority);
}
And the view model looks like this
var TaskListViewModel = function() {
var self = this;
self.currentTask = ko.observable();
self.currentTask(new Task({ name: "", status: false, priority: new Priority({ name: "", value: 0 }) }));
self.tasksArr = ko.observableArray();
self.tasks = ko.computed(function () {
return self.tasksArr.slice().sort(self.sortTasks);
}, self);
self.sortTasks = function (l, r) {
if (l.status() != r.status()) {
if (l.status()) return 1;
else return -1;
}
return (l.priority().value > r.priority().value) ? 1 : -1;
};
self.priorities = [
new Priority({ name: "Low", value: 3 }),
new Priority({ name: "Medium", value: 2 }),
new Priority({ name: "High", value: 1 })
];
// Adds a task to the list
// also saves updated task list to localstorage
self.addTask = function () {
self.tasksArr.push(new Task({ name: self.currentTask().name(), status: false, priority: self.currentTask().priority() }));
self.localStorageSave();
self.currentTask().name("");
};
// Removes a task to a list
// also saves updated task list to localstorage
self.removeTask = function (task) {
self.tasksArr.remove(task);
self.localStorageSave();
};
// Simple test function to check if event is fired.
self.testFunction = function (task) {
console.log("Test function called");
};
// Saves all tasks to localStorage
self.localStorageSave = function () {
localStorage.setItem("romaTasks", ko.toJSON(self.tasksArr));
};
// loads saved data from localstorage and parses them correctly.
self.localStorageLoad = function () {
var parsed = JSON.parse(localStorage.getItem("romaTasks"));
if (parsed != null) {
var tTask = null;
for (var i = 0; i < parsed.length; i++) {
tTask = new Task({
name: parsed[i].name,
status: parsed[i].status,
priority: new Priority({
name: parsed[i].priority.name,
value: parsed[i].priority.value
})
});
self.tasksArr.push(tTask);
}
}
};
self.localStorageLoad();
}
What I want to do in my html is pretty simple.
All tasks I have added are saved to localStorage. The save function is, as you can see, called each time an element has been added & removed. But I also want to save as soon as the status of each task has been changed, but it is not possible to use subscribe here, such as
self.status.subscribe(function() {});
because I cannot access self.tasksArr from the Task class.
Any idea? Is it possible to make the self.tasksArr public somehow?
Thanks in advance!
Try this:
self.addTask = function () {
var myTask = new Task({ name: self.currentTask().name(), status: false, priority: self.currentTask().priority() })
myTask.status.subscribe(function (newValue) {
self.localStorageSave();
});
self.tasksArr.push(myTask);
self.localStorageSave();
self.currentTask().name("");
};

Categories

Resources