I am trying to use fileSaver.js with angular 2 , but am not able to import the module
i am getting cannot find file-saver module error .
Any help is appreciated
This is how I got it to run in my Angular 2 project.
Ran npm install file-saver --save
Then I only had to include import { saveAs } from 'file-saver'; at the top of the file of where I'm calling the save function. You may need to upgrade your TypeScript version to the latest to be able to import.
In your typescript code you can call saveAs with saveAs(new Blob([data], { type: "text" }), 'data.txt');.
If you want typescript data typing you can load @types/file-saver.
@Chris3773 I installed the latest typescript but it still won't import saveAs, I get this error:
Cannot find module 'file-saver'.. It is it node_modules. I'm using webpack could that cause this issue?
I know this will work for webpack version 2.2.0 and awesome-typescript-loader version 3.0.4.
You could also check your tsconfig.json and make sure it's set to node "moduleResolution": "node".
@Chris3773 I made sure I met all those requirements, my error message changed to this now: [at-loader] src/app/lib/api.ts:8:24
TS2307: Cannot find module 'file-saver'.
This is my package.js
"dependencies": {
"@angular/common": "4.0.0-beta.0",
"@angular/compiler": "4.0.0-beta.0",
"@angular/compiler-cli": "4.0.0-beta.0",
"@angular/core": "4.0.0-beta.0",
"@angular/forms": "^4.0.0-beta.0",
"@angular/http": "4.0.0-beta.0",
"@angular/platform-browser": "4.0.0-beta.0",
"@angular/platform-browser-dynamic": "4.0.0-beta.0",
"@angular/platform-server": "4.0.0-beta.0",
"@angular/router": "4.0.0-beta.0",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.15",
"@swimlane/ngx-charts": "^3.1.0",
"@swimlane/ngx-datatable": "^4.1.0",
"angular-2-local-storage": "^1.0.0",
"awesome-typescript-loader": "^3.0.7",
"bootstrap": "^4.0.0-alpha.5",
"bootstrap-loader": "2.0.0-beta.17",
"core-js": "^2.4.1",
"file-saver": "^1.3.3",
"font-awesome": "^4.6.3",
"jquery": "^3.1.1",
"lodash": "^4.17.2",
"moment": "^2.17.1",
"ng2-file-upload": "^1.1.4-2",
"ng2-restangular": "^0.1.23",
"ng2-validators": "^1.6.1",
"ngx-uploader": "^2.0.22",
"reflect-metadata": "^0.1.8",
"rxjs": "^5.0.1",
"tether": "^1.3.8",
"zone.js": "^0.7.2"
},
"devDependencies": {
"@types/core-js": "^0.9.34",
"@types/jasmine": "^2.5.38",
"@types/jquery": "^2.0.32",
"@types/lodash": "^4.14.41",
"@types/node": "^6.0.52",
"@types/protractor": "^4.0.0",
"@types/selenium-webdriver": "^2.53.36",
"angular-2-dropdown-multiselect": "^0.4.0",
"angular2-template-loader": "^0.6.0",
"autoprefixer": "^6.5.4",
"awesome-typescript-loader": "^3.0.7",
"bower-webpack-plugin": "^0.1.9",
"browser-sync": "^2.18.5",
"browser-sync-webpack-plugin": "^1.1.3",
"chunk-manifest-webpack-plugin": "^1.0.0",
"codelyzer": "2.0.0-beta.1",
"compression-webpack-plugin": "^0.3.2",
"copy-webpack-plugin": "^4.0.1",
"copyfiles": "^1.0.0",
"css-loader": "^0.26.0",
"d3": "^4.6.0",
"exports-loader": "^0.6.3",
"extract-text-webpack-plugin": "2.0.0-beta.4",
"font-awesome-sass-loader": "^1.0.2",
"fontawesome": "^4.7.0",
"html-loader": "^0.4.4",
"html-webpack-plugin": "^2.24.1",
"inline-manifest-webpack-plugin": "^3.0.1",
"istanbul-instrumenter-loader": "^1.1.0",
"jasmine-core": "^2.5.2",
"json-loader": "^0.5.4",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.0.0",
"karma-jasmine": "^1.1.0",
"karma-jasmine-diff-reporter": "^0.6.3",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-mocha-reporter": "^2.2.1",
"karma-phantomjs-launcher": "^1.0.2",
"karma-remap-coverage": "^0.1.3",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.8.0",
"lite-server": "^2.2.2",
"mkdirp": "^0.5.1",
"node-sass": "^4.0.0",
"node-static": "^0.7.8",
"null-loader": "^0.1.1",
"phantomjs-prebuilt": "^2.1.14",
"postcss-loader": "^1.2.1",
"protractor": "^4.0.13",
"raw-loader": "^0.5.1",
"remap-istanbul": "0.8.0",
"resolve-url-loader": "^1.6.1",
"rimraf": "^2.5.4",
"rxjs": "^5.2.0",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"to-string-loader": "^1.1.5",
"ts-helpers": "^1.1.2",
"ts-loader": "^1.3.2",
"ts-node": "^1.7.2",
"tslint": "^4.4.2",
"tslint-loader": "^3.2.0",
"typescript": "2.0.10",
"url-loader": "^0.5.7",
"webpack": "^2.2.0-rc.2",
"webpack-dev-server": "^2.2.0-rc.0",
"webpack-manifest-plugin": "^1.1.0",
"webpack-md5-hash": "^0.0.5",
"webpack-merge": "^1.1.1"
}
and my tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"typeRoots": [
"node_modules/@types"
]
},
"exclude": [
"node_modules",
"coverage",
"config",
"report",
"**/*.spec.ts"
],
"awesomeTypescriptLoaderOptions": {
"useWebpackText": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
}
Hi @Chris3773
I got this error:
file_saver_1.saveAs is not a function, can you help me?
Here is my environment:
Angular version: 2.4.3,
"typescript": "2.1.5",
"@types/file-saver": "0.0.0",
In tsconfig.json, set to node "moduleResolution": "node".
In systemjs.config.js, 'file-saver': 'node_modules/file-saver/FileSaver.js'
In my html file:
<img (click)="downloadFile()" src="download-icon.jpeg">
In my ts file:
import { saveAs } from "file-saver";
public downloadFile(): void {
console.log(saveAs); // I got "undefined" from console
saveAs(new Blob(['hello world'], { type: "text" }), 'data.txt');
}
I have exact the same problem with same configuration.
I found a workaround:
removed the import statement on top of my component and then:
let saveAs = require('file-saver');
let file = new Blob([data], { type: 'text/csv;charset=utf-8' });
saveAs(file, 'helloworld.csv');
No idea why this is working...
you need to install the typescript definitions. npm install @types/file-saver --save
it worked for me
@Chris3773 your solutions works with angular cli project, can you please guide what setting would e required for systemjs.config.js ? I added
'file-saver': 'node_modules/file-saver/FileSaver.js',
to map, but its not working.
I have the same problem, @HeinzBiglerCMI code solved it.
The code that is generated when using Typescript+Angular mentioned by @junjunruan is the following:
var file_saver_1 = require('file-saver');
file_saver_1.saveAs(...)
Which is obviously different from the code above that works, but it is the code the readme.md file is saying it should work with require so I'm not sure why it doesn't...
import * as FileSaver from 'file-saver';
FileSaver.saveAs(blob, fileName);
The above options did not work for me - wither it failed during bundling with systemjs-builder or later at runtime. The only thing that worked was using require as shown by @HeinzBiglerCMI
Since I wanted to stick to TS imports and not use require directly, this is the working solution I ended up with:
tsconfig.json
"target" : "es5", "module" : "commonjs", "moduleResolution" : "node"
package.json
"file-saver" : "1.3.3", "@types/file-saver" : "0.0.1"
systemjs.config.js
map: {
'file-saver': 'npm:file-saver'
},
packages: {
'file-saver': {
format: 'global',
main: 'FileSaver.js',
defaultExtension: 'js'
}
}
component.ts
import 'file-saver';
... and then calling later in function ...
var blob = new Blob([data.blob()], {type: 'my-content-type'});
saveAs(blob, 'fileName.xyz');
this issue is pretty wierd, on my case this is already installed
package.json
"@types/file-saver" : "0.0.1"
so I tried to install npm install file-saver --save, I hope there is a way if I install @types/file-saver it will also install the js version.
The solution by @tarmo-randma worked for me, specifically adding
format: 'global',
to the SystemJS config.
I'm using SystemJS and I've tried different solutions, but only this one worked for me:
package.json
"devDependencies": {
"@types/file-saver": "^0.0.1",
},
"dependencies": {
"@angular/core": "^4.4.4",
"file-saver": "^1.3.3",
}
tsconfig.json
"typeRoots": [
"../../node_modules/@types",
"../../node_modules"
],
"types": [
"file-saver"
]
SystemJS config
'file-saver': 'node_modules/file-saver/FileSaver.min.js'
component.ts
import { ResponseContentType } from '@angular/http';
declare var saveAs: any;
this.http.get('testurl', {responseType: ResponseContentType.Blob})
.map(
(res) => {
return new Blob([res.blob()], {type: 'application/pdf'});
})
.subscribe(
(blob: Blob) => {
saveAs(blob, 'testFile.pdf');
}
);
I use Angular 5 and I have same problem:
tsconfig.json
"target" : "es5", "strict" : true, "moduleResolution" : "node"
package.json
"file-saver" : "1.3.3", "@types/file-saver" : "1.3.2"
ERROR in C:/workspace/POC/filesave-angular4-example/angular-frontend/src/app/app.component.ts (4,24): Could not find a declaration file for module 'file-saver/FileSaver'. 'C:/workspace/POC/filesave-angular4-example/angular-frontend/node_modules/file-saver/FileSaver.js' implicitly has an 'any' type.
ERROR in C:/workspace/POC/filesave-angular4-example/angular-frontend/src/app/app.component.ts (4,24): Could not find a declaration file for module 'file-saver/FileSaver'. 'C:/workspace/POC/filesave-angular4-example/angular-frontend/node_modules/file-saver/FileSaver.js' implicitly has an 'any' type.
Is this still an issue after the latest updates?
@Ruffio I just tried it today, got the same issue.
The only way around it for me was @tarmo-randma 's suggestion
Fix: npm install [email protected] --save
The FileSaver.saveAs method is not supported in the 1.3.4 newer version of file saver
@r-paredes-bernal Thank you!!
Well, I don't know what's called "breaking changes" these days but I vote for this one.
I just run: npm install --save @types/file-saver
I am using angular 6 + FileSaver. I needed to download PDF from server. Here is what worked:
npm install file-saver --save
import { saveAs } from 'file-saver';
package.json:
"file-saver": "^1.3.8"
this.http
.get<any>("/pdfs/mypdf.pdf", { responseType: 'blob' as 'json' })
.pipe(
tap(deployments => this.log(`fetched resoure`)),
catchError(this.handleError('getResource', []))
)
.subscribe(data => {
console.log(data);
saveAs(new Blob([data], { type: 'pdf' }), 'data.pdf');
});
@nitinja this type assertion looks plain wrong to me:
responseType: 'blob' as 'json'
Instead, I would declare a variable of type any to bypass the type checks and pass the variable to get() as second argument:
const options: any = ({
responseType : 'blob'
}
);
this.http
.get<any>("/pdfs/mypdf.pdf", options)
@elion I tried only 'blob' and it did not work for me (though I agree mine is more of a hack). I will try your suggestion, thanks.
i tryied this code but have that error can not get file
const headers = new Headers({
'Content-Type': 'application/json',
'Accept': 'application/pdf'
});
const options = new RequestOptions({headers: headers});
options.responseType = ResponseContentType.Blob;
this.http.post('./ng-book2-angular-6-r68.pdf', '', '').map((response) => {
console.log('asdsadsad');
const blob = response.blob();
const filename = 'ng-book2-angular-6-r68.pdf';
FileSaver.saveAs(blob, filename);
});
Can this works for multiple files selected.
Can we zip these files at client -side.
Does it work on all browser. I did try in safari. some issues of security.
Does it work with binary files.
Can this works for multiple files selected.
Depends on browser
Can we zip these files at client -side.
Yes
Does it work on all browser. I did try in safari. some issues of security.
Should be working
Does it work with binary files.
Yes
Would give more proper answer but I'm on a phone
I am looking at this example.
This example for one file download.
headers.append('Accept', 'text/plain');
headers.append('Access-Control-Allow-Origin', '*');
In order to test
ccess to XMLHttpRequest at 'http://192.168.4.1/ebl_data_logs/EBL000013/099_20190518_111653.ebl' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Seems like the file is coming from a server?
Can't you just use Content-Disposition attachment header instead to save the file instead of using FileSaver?
No sure what you mean. give example typescript code.
Ho can pipe multiple HTTP get file request sequential. I do not want to send simulations HTTP get request. I have list of URLs for each file to download. how can I pipe in sequential to down file by file programmatically.
No sure what you mean. give example typescript code.
Nope. It's server side code - I don't know what stack you are using koa, express, uws... deno or node
zip all files on the server and then give that to the user?
I want to download multiple files using http get file. I know urls of all selected file.
FileSave for blob is not working for it. I can trigger hyper link click.
I need to download file by file. one a t time.
http.getFile(url).subscribe(blob => {
document.getElementById(file_name).click();
}, errmsg => {
});
Okey, if you insist in using multiple url's and not do it on the server side... wish i recommend
have a look at some of this tools:
if you go with the StreamSaver route, then i think Angular's http client isn't a good candidate to handle ajax as you would need the ReadableStream from the response object
es7
const urls = [
'https://httpbin.org/get'
].values()
new ZIP({
async pull (ctrl) {
const it = urls.next()
if (it.done) {
ctrl.close()
} else {
const res = await fetch(it.value)
const stream = () => res.body
const name = `/folder/foo-${Math.random()}.bin`
ctrl.enqueue({ name, stream })
}
}
}).pipeTo(streamSaver.createWriteStream('archive.zip'))
es6
new ZIP({
pull (ctrl) {
const it = urls.next()
if (it.done) {
ctrl.close()
} else {
return fetch(it.value).then(res => {
const stream = () => res.body
const name = `/folder/foo-${Math.random()}.bin`
ctrl.enqueue({ name, stream })
})
}
}
})
Thanks for example. I appreciate. this is JS example. I am using angular 2x/cli TypeScript. Any example for TypeScript. Can I use JS within my angular 2.x code.
I am using angular 2x/cli TypeScript. Any example for TypeScript. Can I use JS within my angular 2.x code.
The fact that you are asking this question seems very ....
TypeScript is a superset of javascript and any javascript can be used in typescript but not the other way around.
You should be able to understand and convert any javascript to typescript if you like.
You should most definitely learn JavaScript before learning TypeScript
You should learn the language before using any framework too
Sorry for asking basic question. I am not expert in JS.
I learned JS/angular 1.x and used before. It looks to be some work either to write JS code as typescript code or use JS within my TypeScript angular application. I will try later.
If you have time. Do help me with example code to use above JS code which download and zip it as part of simple TypeScript/Angular as example.
new ZIP
Uncaught ReferenceError: ZIP is not defined
I have tried including all these JS.
<script src="../node_modules/streamsaver/StreamSaver.js"></script>
<script src="../node_modules/jszip/dist/jszip.js"></script>
<script src="./zip.js/WebContent/zip.js"></script>
<script src="./zip-stream.js"></script>
Then you have probably not included zip-stream.js properly? do you get 404 when loading the file?
try new window.ZIP if that helps
And why load both zip stream and zip.js?
I managed to use file saver.
https://www.npmjs.com/package/ngx-filesaver
It is working except on safari web browser on apple device.
The FileSaver.saveAs method is not supported in the 1.3.4 newer version of file saver
Thanks, it works for me!
"file-saver" : "1.3.3"
where can i find SystemJS config file?? there is no such file in my project
Most helpful comment
import * as FileSaver from 'file-saver';
FileSaver.saveAs(blob, fileName);