React:write to json file or export/download [no server]

I got really confused with file I/O in JS/TS. most examples I see works with DOM and has browser-based solutions.

Also, I did not understand how to make fs work, it seems to need a webpack config, where I use CRA and do not want to eject.

in a React component I want to fetch some data from a server then save them as a JSON file in the project folder (the same path, root, public folder, no matter) or directly download (no button needed).

//data type just in case inteface IAllData{ name:string; allData:IData[];} 

so after fetching some data want to save them to name.json

public componentDidMount(){ this.fetchData().then(()=>this.saveData()) } public async fetchData(){/* sets data in state*/} public saveData(){ const {myData}=this.state; const fileName=myData.name; const json=JSON.stringify(myData); const blob=new Blob([json],{type:'application/json'}) /* How to write/download this blob as a file? */ } 

here trying window.navigator.msSaveOrOpenBlob(blob, 'export.json'); did not work

note: I know it has security risks, it is not for production. save the file in the project folder is preferred but a download is totally ok.

3 Answers

I had a blob containing data and I had found a solution on stackoverflow and manipulated a bit, and succeded to download as a xlsx file. I am adding my code below, it might help you, too.

const blob = await res.blob(); // blob just as yours const href = await URL.createObjectURL(blob); const link = document.createElement('a'); link.href = href; link.download = "file.xlsx"; document.body.appendChild(link); link.click(); document.body.removeChild(link); 

EDIT: I have written a function for your case, you can use below function, but be careful about "fileName" (not in "this.state" object in my case) and "myData" object that is stored in "this.state" object.

const downloadFile = async () => { const {myData} = this.state; // I am assuming that "this.state.myData" // is an object and I wrote it to file as // json const fileName = "file"; const json = JSON.stringify(myData); const blob = new Blob([json],{type:'application/json'}); const href = await URL.createObjectURL(blob); const link = document.createElement('a'); link.href = href; link.download = fileName + ".json"; document.body.appendChild(link); link.click(); document.body.removeChild(link); } 
0

For the ones like me here that are looking for an easier solution when you already have your JSON as a variable:

 <button href={`data:text/json;charset=utf-8,${encodeURIComponent( JSON.stringify(YOURJSON) )}`} download="filename.json" > {`Download Json`} </button> 
3
<button type="button" href={`data:text/json;charset=utf-8,${encodeURIComponent( JSON.stringify(YOURJSON) )}`} download="filename.json" > {`Download Json`} </button> 

if you are using the Loic V method just ad the type for the button on the button element and should work just fine.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like