I am trying to create an app that, with info given by the user, gets a PDF formulary from local assets, writes that info on it and then downloads it.
It works perfectly fine on browser and I get the file sucessfully, but when I create the app build and I try it in the movile device, just nothing happens. I get messages of "File downloaded!" or any log I put, but the file just never start downloading. I already have storage permissions. Just ends the function normally but ignoring the download.
I use the unpkg library to download, but also tried with SaveAs and creating an <a.href> then click it but I got excactly the same result.
This is the full function:
async generateDecklist()
{
const formUrl=('../../../assets/decklist.pdf');
const formPdfBytes = await fetch(formUrl).then(res => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(formPdfBytes);
const form = pdfDoc.getForm();
const formFields = form.getFields()
//START FILLING FORM
//Deck Name & Nation
form.getTextField('Deck NameRow1').setText(this.deck.name);
form.getTextField('ClanRow1').setText(this.deck.nation);
for (let i = 0; i<this.deck.decklist.length; i++)
{
const cs = this.deck.decklist[i];
const card = Global.cards.find(e => e.id == cs.cardId);
//Card Name
const mainDeckCard = "Main deck 50 cardsRow" + (i+1);
form.getTextField(mainDeckCard).setText(card.name);
//Card Grade
formFields[16+i].setText(card.grade.toString());
//Card Amount
const mainDeckAmount = "Main deck Qty" + (i+1);
form.getTextField(mainDeckAmount).setText(cs.amount.toString());
//Card set (Only if there is only one set)
if(card.sets.length ==1)
{
const mainDeckSet = 'No.'+ ((i+13)>=15? (i+14) : (i+13));
form.getTextField(mainDeckSet).setText(card.sets[0]);
}
//Card trigger or sentinel
let triggerOrSentinel ='';
if(card.type == 'Trigger Unit')
{
triggerOrSentinel += card.trigger;
}
if(card.keywords.includes('Sentinel'))
{
triggerOrSentinel += triggerOrSentinel==''? 'Sentinel' : '/Sentinel';
}
const mainDecktrigger = "Main deck Row" + (i+1);
form.getTextField(mainDecktrigger).setText(triggerOrSentinel);
}
//END FILLING FORM
//PROBLEM STARTS HERE
const pdfBytes = await pdfDoc.save();
download(pdfBytes, `${this.deck.name}_decklist.pdf`, "application/pdf");
modalController.dismiss();
}
Related
I am currently making a node API where the user will be able to use my paint app. The user will be able to draw a picture and thereafter "add it to gallery" where it will land into my gallery.html where it will be displayed along with a description (title if you may) of the users painting. From there, the user will have the option to edit the description of their added painting and also delete it, if so desired. However i have thus far managed to make the image be sent to the gallery as a table of the Image, and description but not managed to get the edit and delete made to work yet. Any suggestions what code i could put in to address this issue with the style of code I have put in?
the code i am showing is solely the mechanics of where the crud operation is happening. the actual paint js, html and css is in other files.
best regards!
this is what my code looks like currently:
const loadImages = async () => {
const res = await fetch('/images')
if (res.ok){
console.log('ok')
const gallery = document.getElementById('gallery')
const data = await res.json()
//the creation of table upon adding to gallery
const table = document.createElement('table')
table.classList.add('galleryTable')
const tableHeader = document.createElement('tr')
table.classList.add('tableTR')
const tableHeaderImage = document.createElement('th')
tableHeaderImage.innerText = 'Paintings'
const tableHeaderDesc = document.createElement('th')
tableHeaderDesc.innerText = 'Description'
const tableHeaderControllers = document.createElement('th')
tableHeaderControllers.innerText = 'Options'
tableHeader.appendChild(tableHeaderImage)
tableHeader.appendChild(tableHeaderDesc)
tableHeader.appendChild(tableHeaderControllers)
table.appendChild(tableHeader)
//a foreach loop to continously adding and collecting the saves images into the gallery
data.forEach(image =>{
const tableRow = document.createElement('tr')
const tableDataImage = document.createElement('td')
const img = document.createElement('img')
img.src= image.imagedata
tableDataImage.appendChild(img)
tableRow.appendChild(tableDataImage)
const tableDataDesc = document.createElement('td')
tableDataDesc.innerText = image.description
tableRow.appendChild(tableDataDesc)
const tableDataControllers = document.createElement('td')
tableDataControllers.innerText = 'Options'
tableRow.appendChild(tableDataControllers)
table.appendChild(tableRow)
})
gallery.appendChild(table)
} else {
console.log(res)
}
}
loadImages()
I am trying to figure out how to make a script to run a function based on an answer provided, at the moment my script creates and populates a word doc with answers provided from a google form. I want to streamline it so that I can use one google form to create different documents based on an answer provided rather than creating multiple google forms. I am very new to JavaScript and I am pretty sure I need an if statement at the beginning of everything, but I don't know what I should write or where it should go. This is my script:
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs');
menu.addToUi();
}
function createNewGoogleDocs(){
const googleDocTemplate = DriveApp.getFileById('google file goes here');
const destinationFolder = DriveApp.getFolderById('google folder goes here');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Response');
const rows = sheet.getDataRange().getValues();
rows.forEach(function(row,index) {
if (index === 0) return;
if (row[9]) return;
const copy = googleDocTemplate.makeCopy(`${row[5]} document name goes here`, destinationFolder);
const doc = DocumentApp.openById(copy.getId())
const body = doc.getBody();
body.replaceText('{{Name}}', row[5]);
body.replaceText('{{To}}', row[6]);
body.replaceText('{{Items}}', row[7]);
body.replaceText('{{Reasoning}}', row[8])
body.replaceText('{{Submitter}}', row[1]);
body.replaceText('{{Role}}', row[2]);
body.replaceText('{{Time}}', row[3]);
body.replaceText('{{Discord}}', row[4]);
doc.saveAndClose();
const url = doc.getUrl();
sheet.getRange(index + 1, 10).setValue(url)
})
}
I'm trying to fill pdf form usinf PDFLib js.
In my localhost it works fine but after deployment "field.constructor.name" return "t" type. and the data is no filled.
there is no error, but nothing happened.
const pdfDoc = await PDFDocument.load(formPdfBytes);
// Register the `fontkit` instance
pdfDoc.registerFontkit(fontkit);
// Embed our custom font in the document
const customFont = await pdfDoc.embedFont(fontBytes, { subset: true });
// Get the form containing all the fields
const form = pdfDoc.getForm();
const fields = form.getFields()
fields.forEach(field => {
//HERE THE PROBLEM!!
const type = field.constructor.name // GOT "t"
const name = field.getName();
I found the problem. The font file was problematic.
I wanted to delete the file from storage when a data node is deleted from the realtime database. the name of the file to be deleted is taken before deleted. The name of the file is saved in the node in child named "imageTitle". The code works fine before implementing the file delete code. I mean the nodes get deleted perfectly.
When I implement the file delete code the rest doesn't work, but there is no any errors. The code after file delete doesn't work. I dunno why.
This is for an academic final project.
There's a folder named images in the bucket, and the file I need to delete is in there. The file name is taken from the child in the node which is to be deleted in the realtime database named imageTitle:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.changetime = functions.database.ref('/posts/{pushId}')
.onCreate((snapshot, context) => {
const editDate = Date.now()
datas = snapshot.val();
return snapshot.ref.update({editDate})
})
const CUT_OFF_TIME = 1 * 60 * 1000;
/**
* This database triggered function will check for child nodes that are older than the
* cut-off time. Each child needs to have a `timestamp` attribute.
*/
exports.deleteOldItems = functions.database.ref('/posts/{pushId}').onWrite(async (change,
context) => {
const ref = change.after.ref.parent; // reference to the parent
const now = Date.now();
const id = context.params.pushId;
const cutoff = now - CUT_OFF_TIME;
const oldItemsQuery = ref.orderByChild('createdDate').endAt(cutoff);
const snapshot = await oldItemsQuery.once('value');
const getImageTitle = admin.database().ref(`/posts/${id}/imageTitle`).once('value');
return getImageTitle.then(imageTitle => {
console.log('post author id', imageTitle.val());
const imageName = imageTitle.val();
const filePath = 'images/' + imageName;
const path = `images/${imageName}`;
const bucket = app.storage().bucket();
return bucket.file(path).delete().then(() =>{
console.log(`File deleted successfully in path: ${imageName}`)
/* The problem is here. the code doesn't work after file.delete function. no errors. but doesn't work
if I remove that piece of code the other codes work fine. I mean the realtime database nodes get deleted and updated perfectly */
const updates = {};
snapshot.forEach(child => {
updates[child.key] = null;
if(updates[child.key] == null){
admin.database().ref(/post-likes/+id).remove();
}
})
return ref.update(updates);
});
});
[my storage looks like this][1]});
There's a folder named images in the bucket, and the file I need to delete is in there. The file name is taken from the child in the node which id to be deleted in the realtime database imageTitle:
enter image description here
I think this is the problem:
const filePath = 'images/' + imageName;
const path = `images/${imageName}`;
You should be using filePath not path in your bucket reference. const path = `images/${imageName}`; is wild-card syntax used when querying, not when assigning variables....think you stayed in 'Dart' mode here:-). Not sure what path contains, therefore, but console.log it to see.
Here is some code that I use to delete images from my storage bucket that works perfectly. First, a couple of things to check (best done using console.log, never assume you know what is in the variable), and do:
Ensure imageName, filePath, path and bucket contain what they should contain.
Include the .catch block in your code to check if there actually is an error
I am not clear if console.log(`File deleted successfully in path: ${imageName}`) is executing but if it isn't then your file.delete must be throwing an error which the catch block should trap.
The code snippet:
const oldProfileImagePath = "profileImages/" + authenticatedUserId + "/" + oldProfileImageName;
return bucket.file(oldProfileImagePath).delete()
.then(function () {
console.info("Old Profile Image: " + oldProfileImagePath + " deleted!");
})
.catch(function (error) {
console.error("Remove Old Profile Image: " + oldProfileImagePath +
" failed with " + error.message)
});
I currently have completed a tutorial which reads/writes to a Firebase using Angular2.
Need some help with the below function within the firebase.service.ts
addListing(listing){
let storageRef = firebase.storage().ref();
for (let selectedFile of [(<HTMLInputElement>document.getElementById('image')).files[0]]){
let path = `/${this.folder}/${selectedFile.name}`;
let iRef = storageRef.child(path);
iRef.put(selectedFile).then((snapshot) => {
listing.image = selectedFile.name;
listing.path = path;
return this.listings.push(listing);
});
}
}
Code that runs the function
Within the add-listing.component.html file
<form (submit)="onAddSubmit()">
Within the add-listing.component.ts file
onAddSubmit(){
let listing = {
title:this.title,
city:this.city,
owner:this.owner,
bedrooms:this.bedrooms,
price:this.price,
type:this.type
}
this.firebaseService.addListing(listing);
this.router.navigate(['listings']);
}
This all works correctly - however I want to change the function to allow data to be pushed to the database without having to upload a image or file - currently the function wont run unless a image is included in the form.
Thanks for all your help.