How to print pdf from server after button click in Angular 2+ - javascript

On my page I have button that should download concrete pdf file from backend and open the printing window. I tried answers here that included some blob stuff. It did not work. Tried to change route and embed the file in the HTML and after files would be downloaded to call window.print() on the page, but page was blank. Tried also printJS, but wasn't able to make it work, since it kept showing printJS is not a part of onclick function or something like that. Any advice would be helpful.

The only solution I came up with was to do it like this:
printPdf(){
this.network.getPdfHash()
.pipe(take(1))
.subscribe((res) => {
//res === url to the location of the PDF
let win = window.open(res, "_blank");
win.focus();
win.addEventListener(
"load",
() => {
setTimeout(() => {
//to give time for the browser to load the pdf
win.window.print();
}, 250);
},
true
);
});
}

Related

Issue with adobe_dc_view_sdk pdf file preview

I am testing the adobe document cloud view sdk on https://www.thacherandrye.com/dinner , https://www.thacherandrye.com/the-shed , https://www.thacherandrye.com/brunch
Sometimes, the file preview is not working and all I can get on the screen is a large white space(No errors in the console). Whenever I load the page for the first time, in a browser or incognito window, the file appears on the preview but after reloading or moving to another page with a preview, the file seems to disappear.
I checked for the key being wrong/expired but then it should not have loaded the file even for the first time.
Below is the Javascript code I am using for the api:
$(document).ready(function() {
document.addEventListener("adobe_dc_view_sdk.ready", function(){
var adobeDCView = new AdobeDC.View({ clientId: SOME_KEY, divId: $('#adobeDcViewId{Id}').val() });
adobeDCView.previewFile({
content: { location: { url: $('#hdnUrl{Id}').val() } },
metaData: { fileName: $('#hdnFileName{Id}').val() }
},
{
showDownloadPDF: $('#hdnRestrictDownload{Id}').val() !== 'true',
showPrintPDF: $('#hdnRestrictDownload{Id}').val() !== 'true'
});
});
});
Tech stack: .net framework 4.7.2, jQuery 3.6.0
I tried to help you on our forums, but I don't know if you saw my response. This line worries me:
$('#adobeDcViewId{Id}').val()
The value that needs to be passed to divId needs to be a string, and needs to match the ID of the div element. Also, #adobeDcViewId{Id} doesn't look like a valid CSS selector to me.
Can you try changing this to a hard-coded value of the div on your site?

How to simulate video playing in Netflix without reloading the page?

I'm trying to write a chrome extension where I want to be able to start playing a Netflix video from the main page without having to navigate to the video URL using something like window.location.href = '...', which would cause the page to reload. I want to do this without reloading the page because the content script of a chrome extension is re-injected every time a page reload happens, which I don't want to happen every time.
For example, if you go to the netflix website and click on a movie, the video will start playing without actually doing a full page reload. This suggests that changes to the DOM are triggered via JavaScript? Does anyone know how this is done?
I tried looking at some of the Javascript code to see if there was a function I could call to trigger some sort of event, but the code was too complicated to understand. So another approach I thought of was to do a fetch with the url of the video that I want to play, and then simply replace the contents of the body element with that of the fetched html. For example:
fetch("https://www.netflix.com/watch/70174779")
.then(function(response) {
response.text().then(function(html) {
var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
document.getElementsByTagName(
"body"
)[0].innerHTML = doc.getElementsByTagName("body")[0].innerHTML;
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
});
However, when I run this in the Chrome DevTools console, it just results in an empty page. I don't get any helpful errors either. I also tried replacing the entire html contents:
fetch("https://www.netflix.com/watch/70174779")
.then(function(response) {
response.text().then(function(html) {
document.open();
document.write(html);
document.close();
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
});
But this also didn't work, and I get a bunch of errors in the console.

Download S3 file from pre-signed URL without popup blocker

I have a Meteor application where I'm downloading files from S3 using pre-signed URLs (need to be generated with an API call).
I was having an issue with popup blockers preventing a new tab from opening with the url generated by the AWS-SDK so I changed my code to the following:
downloadDocument(document, event) {
// open tab immediately to prevent popup blocker
const myNewTab = window.open();
// call method to generate url
Meteor.call('Events.Methods.Document.Download', { key: document.key, eventId: event._id }, (error, res) => {
if (error) { ... } // removed handle error code
// if url generated, set tab location to url
if (res) myNewTab.location.href = res;
// auto close the tab after 1 second
myNewTab.setTimeout(() => { myNewTab.close(); }, 1000);
});
}
This code is working for the most part but it doesn't feel very clean. Also if the API call ever takes more than 1 second (slow internet) then the tab will close before the download begins
How can I change this so that I can wait for the download to happen, before closing the tab? Or a similar solution that would result in me ensuring the downloads always go through without popup blockers being an issue?
Thanks
You are always going to run afoul of pop-up blockers if you open a new window.
What you should do is generate an <a href="my-custom-server-generated-url" download> link with the download property, which will force a download without needing a new window.
Then you also don't need to close the window on a timer (which wasn't a good approach in the first place)
This was happening only in Safari, so we switched to always downloading the file instead of opening in a new window in Safari/mobile.

Retrieve html content of a page several seconds after it's loaded

I'm coding a script in nodejs to automatically retrieve data from an online directory.
Knowing that I had never done this, I chose javascript because it is a language I use every day.
I therefore from the few tips I could find on google use request with cheerios to easily access components of dom of the page.
I found and retrieved all the necessary information, the only missing step is to recover the link to the next page except that the one is generated 4 seconds after loading of page and link contains a hash so that this step Is unavoidable.
What I would like to do is to recover dom of page 4-5 seconds after its loading to be able to recover the link
I looked on the internet, and much advice to use PhantomJS for this manipulation, but I can not get it to work after many attempts with node.
This is my code :
#!/usr/bin/env node
require('babel-register');
import request from 'request'
import cheerio from 'cheerio'
import phantom from 'node-phantom'
phantom.create(function(err,ph) {
return ph.createPage(function(err,page) {
return page.open(url, function(err,status) {
console.log("opened site? ", status);
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function(err) {
//jQuery Loaded.
//Wait for a bit for AJAX content to load on the page. Here, we are waiting 5 seconds.
setTimeout(function() {
return page.evaluate(function() {
var tt = cheerio.load($this.html())
console.log(tt)
}, function(err,result) {
console.log(result);
ph.exit();
});
}, 5000);
});
});
});
});
but i get this error :
return ph.createPage(function (page) {
^
TypeError: ph.createPage is not a function
Is what I am about to do is the best way to do what I want to do? If not what is the simplest way? If so, where does my error come from?
If You dont have to use phantomjs You can use nightmare to do it.
It is pretty neat library to solve problems like yours, it uses electron as web browser and You can run it with or without showing window (You can also open developer tools like in Google Chrome)
It has only one flaw if You want to run it on server without graphical interface that You must install at least framebuffer.
Nightmare has method like wait(cssSelector) that will wait until some element appears on website.
Your code would be something like:
const Nightmare = require('nightmare');
const nightmare = Nightmare({
show: true, // will show browser window
openDevTools: true // will open dev tools in browser window
});
const url = 'http://hakier.pl';
const selector = '#someElementSelectorWitchWillAppearAfterSomeDelay';
nightmare
.goto(url)
.wait(selector)
.evaluate(selector => {
return {
nextPage: document.querySelector(selector).getAttribute('href')
};
}, selector)
.then(extracted => {
console.log(extracted.nextPage); //Your extracted data from evaluate
});
//this variable will be injected into evaluate callback
//it is required to inject required variables like this,
// because You have different - browser scope inside this
// callback and You will not has access to node.js variables not injected
Happy hacking!

Filepicker modal only displayed after initial page load in meteor

When I call filepicker.pickAndStore() for the first time in a template everything works fine. Also closing the modal and clicking the button again works fine (modal is displayed again). When I click on a link inside my meteor app to get to another page (of course via html5 pushstate like on every meteor page, no standard a links with a real page refresh) and then go back to the page with the filepicker stuff in it, the button does not do anything anymore. The filepicker modal or anything is NOT displayed. And i also tried call back function as given in the documentation. I'am describing my code below
Template.content.events({
'click #top_add_file': function (evt) {
evt.preventDefault();
console.log("upload file button is clicked")
Session.set("widgetSet", false);
if (!Session.get("widgetSet")) {
var cb = function () {
filepicker.pickAndStore(
{
mimetypes: ['application/pdf', 'application/msword', 'application/mspowerpoint', 'text/plain'],
container: 'window',
services: ['COMPUTER'],
folders: true
},
{
location: 'S3'
},
function (InkBlob) {
console.log("InkBlob="+InkBlob)
InkBlob.forEach(function (ib) {
Meteor.call("createContent", ib, Meteor.content_file, function (error, result) {
if (error) {
FlashMessages.sendError("Error in saving file")
} else {
FlashMessages.sendSuccess("Successfully Saved File")
}
})
})
},
function (FPError) {
FlashMessages.sendError("Error in uploading file. Please try again")
}
)
};
loadPicker(Meteor.fpkey, cb);
}
},
The answers to this StackOverflow question may help:
Integrating Filepicker.IO with Meteor
One of them highlights an atmosphere package for filepicker:
https://github.com/guido4000/loadpicker
Also, this example shows integrating a 3rd-party modal component into meteor:
https://github.com/alanning/meteor-modal-example

Categories