2

I have a MERN stack web app that makes heavy use of rx.js "Observables". I have been searching for docs, plugins, npm modules, etc. that enable my app to do an image file upload (binary file) to a Node.js api endpoint (endpoint utilizes the npm module "multer" on the receiving end).

I have been unable to find tutorials, libraries or modules that support this specific functionality using the MERN + Observables stack. Google returns examples for Angular only. And there appears to be no relevant questions of this type on stackoverflow.

I have a complex form, some fields are required, and some are optional content. One piece of required input is an image file for upload. My aim/hope is to deliver all this data to the server using a chained series of Observables.

Is there a react plugin/module/library similar to axios that uses observables, or am I just guilty of "wishful thinking"? I am wondering if this is possible, and if anyone can point me towards a tutorial, article, example, github, etc., or just straight up show me the way.

Note: I don't have a problem with implementing a special one-off case and using a library like axios, or even just writing raw JS XHR to get it done, just thought it would be nice, clean, and homogenous to also accomplish this task with observables... also, I am fairly new to observables, so it's possible I could be missing something important or simply not know that this kind of functionality is not supported with this library (rx.js).

Any help, advice, or insight would be useful! Links to docs/articles/tutorials are greatly appreciated! Thanks in advance!

dwjohnston
  • 11,163
  • 32
  • 99
  • 194
hypervisor666
  • 1,275
  • 1
  • 9
  • 17
  • 1
    So you are wondering how to send file using `rxjs.ajax` module? – Oles Savluk Oct 12 '19 at 02:02
  • may be show us some of the code you have tried so far? – Fan Cheung Oct 12 '19 at 02:56
  • @OlesSavluk apparently I was having a brain fart, yes, I'm trying to figure out how to perform an ajax post using rxjs. I found another question on stackoverflow that indicates that Observables don't natively support multipart/form-data, which is precisely what I need. Looks like I'll have to build something custom or fallback and use an ajax library that does support form data. Here's the link that contained a similar question and the answer I needed in the comments section: https://stackoverflow.com/questions/43151306/posting-mutipart-form-data-with-rxjs-ajax. Thanks, your info was great! – hypervisor666 Oct 12 '19 at 04:51

1 Answers1

2

You can supply FormData instance as rxjs.ajax body parameter, and browser will automatically set proper Content-Type header.

See example code:

const { ajax } = rxjs.ajax; // = require("rxjs/ajax")
const { fromEvent } = rxjs; // = require("rxjs")
const { mergeMap } = rxjs.operators; // = require("rxjs/operators")

const fileInput = document.getElementById("file");
const res$ = fromEvent(fileInput, "change").pipe(
  mergeMap(e => {
    const { files } = e.target; 

    const body = new FormData();
    body.append("some-field", "fome-field-value");
    body.append("file", files[0]);

    return ajax({
      url: 'https://httpbin.org/post',
      method: 'POST',
      body
    });
  })
);

const htmlSubscription = res$
  .subscribe(e => {
    const response = JSON.stringify(e.response, null, 2);
    document.getElementById('root').innerHTML = `
      <div>
        <span><b>POST</b> https://httpbin.org/post</span>
        <pre>${response}</pre>
      </div>`;
  });
<script src="https://unpkg.com/rxjs@6.5.3/bundles/rxjs.umd.min.js"></script>
<input type="file" id="file" />

<div id="root">select file and see what happens...</div>

Also take a look:

Oles Savluk
  • 4,315
  • 1
  • 26
  • 40
  • I am marking yours as the correct answer because somehow you figured out exactly what I was looking for despite my lack of concise language. You provided me with the missing link "multipart/form-data" as well as demonstrating how to weave that kind of request through an observable! I want to express my sincere and humble gratitude, appreciation, and thanks for taking the time and having the patience to go to all this trouble to answer my question! You rock! Very much appreciated!!! – hypervisor666 Oct 12 '19 at 08:31