The below code is what take final action to save the data to the target DB.
const onFileUpload = (e) => { const files = Array.from(e.target.files); const formData = new FormData(); formData.append('attachable_type', attachableType); formData.append('attachable_id', attachableId); if (files.length > 0) { const file = files[0]; formData.append('file', file); upload(dispatch, { body: formData, }).then(() => {}); } };
Now I am building an offline app, where when no internet is available I would like to save this request to indexdb. I have the whole setup. All I want to know how can I save a FormData
instance to indexdb so that I can later fetch it from indexdb and send it to server for permanent storage. I need some ideas. I tried some google but I don’t see any direct answer to the following question. I am using idb
npm plugin. The below update function I will be using to as an interface to talk to the db.
export async function update(attrs) { const db = await createAppDB(); const tx = db.transaction('attachments', 'readwrite'); const store = tx.objectStore('attachments'); store.put(attrs); await tx.done; }
Advertisement
Answer
You could extract the FormData through the Body.formData()
method, and then retrieve its content by getting this FormData’s entries and store these to IDB:
(async () => { // in ServiceWorker while disconnected const request = buildRequest(); // extract the FormData const fd = await request.formData(); const serialized = { url: request.url, method: request.method, mode: request.mode, body: [ ...fd ] // you may need more fields from request }; // you can now store the entries in IDB // here we just log it console.log( "stored", serialized ); // and to build back the Request const retrieved = { ...serialized }; const new_body = new FormData(); for( let [ key, value ] of retrieved.body ) { new_body.append( key, value ); } retrieved.body = new_body; const new_request = new Request( retrieved ); // fetch( new_request ); // remember to remove from IDB to avoid posting it multiple times console.log( "sent", [...new_body] ); } )(); // returns the same kind of Request object a ServiceWorker would intercept, // whose body is a FormData function buildRequest() { const fd = new FormData(); fd.append( "some-key", "some-data" ); fd.append( "the-file", new Blob( [ "hey" ] ), "file.txt" ); return new Request( "", { method: "POST", body: fd } ); }
Too bad we can’t just put POST requests in the Cache API, it would have been a lot cleaner…