I'm using Angular2 to download a generated .docx file from my express server. The file is generated by a tool and saved on the server, and then sent to the frontend.
My browser logging says that the length of the result is larger than 0, but the blob being sent has no body, so the actual contents of the document can't be found.
I've followed several examples and tutorials, especially this one, but no result so far. What am I doing wrong?
express backend:
generate(req: express.Request, res: express.Response): void {
try {
var docxGenerator = new DocxGenerator();
docxGenerator.generate((error, filename) => {
if (error) res.send(error);
if (filename) {
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
res.setHeader('Content-disposition', 'attachment; filename=GeneratedFile.docx');
var file = fs.readFileSync(filename);
res.end(file);
}
});
} catch (error) {
res.send(error);
}
}
Angular2 Service:
export class DocxTemplaterService {
// declarations left out for brevity
constructor(
private http: Http,
private authService: AuthenticationService
) {
this.headers = new Headers({'Content-Type': 'application/json'});
this.headers.append('Authorization', 'Bearer ' + this.authService.token());
this.options = new RequestOptions({ headers: this.headers });
}
generateDocx(): Observable<any> {
this.options.responseType = ResponseContentType.Blob;
return this.http
.post(this.docxUtilUrl + '/create', JSON.stringify(module), this.options)
.map(response => {
console.dir(response);
response.blob();
})
.catch(this.handleError);
}
private handleError(error: any) {
return Promise.reject(error.message || error);
}
}
Angular2 Component:
generateDocx(module: Module) {
this.docxTemplateService
.generateDocx()
.subscribe(
data => {
console.log(`Word data: ${data}`);
if (data !== undefined)
// save file somehow
else console.log('No file to download.');
},
error => { this.alertService.error(error); },
() => this.alertService.success("Success", true)
);
}
The Blob contents logged in Chrome console:
size: 68192
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
__proto__: Blob
So... a size without contents. Help is apreciated!
You should explicitly return response.blob
from function
as you used parenthesis in arrow function.
generateDocx(): Observable<any> {
this.options.responseType = ResponseContentType.Blob;
return this.http
.post(this.docxUtilUrl + '/create', JSON.stringify(module), this.options)
.map(response => {
console.dir(response);
return response.blob(); //need to return response blob
})
.catch(this.handleError);
}
Or rather you can make that map
function one liner
.map(response => response.blob())
Similar answer here