So, I've been trying to redirect a URL and open it in a new tab, but I've not been able to do it.
I have an API that's returning me a plain text that's coming as a BLOB object, but actually, it's just a URL. I need to open that URL in a new tab.
This is the code I'm trying to get to work:
this.printingService.getCvUrl(options).subscribe(
url => {
const downloadURL = window.URL.createObjectURL(url);
window.open(downloadURL, '_blank');
}
);
It calls the getCvUrl method, that it's this:
getCvUrl(options: { remoteUrl: string, paperHeight?: string, paperWidth?: string }): Observable<any> {
const user = this.authenticationService.getCurrentUser();
const PRINT_SERVICE = `/api/users/${user.id}/syncMyCV`;
const CV_SERVICE = 'https://cv.url/template/ce';
const formData = new FormData();
formData.append('remoteURL', CV_SERVICE + options.remoteUrl);
formData.append('paperHeight', options.paperHeight);
formData.append('paperWidth', options.paperWidth);
const token = this.authenticationService.getToken();
return this.http.post(
PRINT_SERVICE,
formData,
{
headers: {
'Anonymous': 'undefined',
'accept': '*/*',
'Authorization': token
},
responseType: 'blob'
}
).pipe(catchError(err => {
this.errorService.handleError(err);
return observableOf(null);
}));
}
As a response, this is currently opening a new tab for me, with the text of the URL as content, but not in the browser's URL field.
I've tried all of these approaches:
First I tried navigating with the router, but of course, it didn't work, as I'm trying to open an external URL.
this.printingService.getCvUrl(options).subscribe(
url => this.router.navigate([url])
);
Then, looking at some of the questions, I tried to modify the href attribute of the window location. It didn't work either
this.printingService.getCvUrl(options).subscribe(
url => window.location.href = url
);
Then, following another answer, I changed to the window open method, and it opened a new tab, but then there was giving me a 404 error
this.printingService.getCvUrl(options).subscribe(
url => window.open(url, '_blank')
);
After looking over it, I realized I was trying to redirect a blob object as if it was a URL string, so some conversion was needed. Then I tried using a method I created in the same service I'm using.
this.printingService.getCvUrl(options).subscribe(
url => {
this.printingService.view(url);
}
);
And then it called the view() method in the printing service, which is implemented as follows:
view(data: ArrayBuffer, filename = 'resume.pdf') {
if (!!data) {
const blob = new Blob([data], {type: 'application/pdf'});
const downloadURL = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadURL;
link.download = filename;
link.click();
}
}
But the problem is that this method downloads a pdf, but it's not even what I want, so I decided to take what I need from that method, and adapt it. Then I got to the current solution above, which is not working either:
this.printingService.getCvUrl(options).subscribe(
url => {
const downloadURL = window.URL.createObjectURL(url);
window.open(downloadURL, '_blank');
}
);
Up to this point, I ran out of ideas. Does anyone have any other approach I have not tried?
Solution using the accepted answer:
In the getCvUrl method, I changed this line:
responseType: 'blob'
by this:
responseType: 'text'
as the answer coming from the API will always be a text/plain response. And the final code looks like this:
this.printingService.getCvUrl(options).subscribe(
url => {
const downloadLink = document.createElement('a');
downloadLink.href = url;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
);