19

I'm trying to get the value from a simple ajax request, but I don't understand how to do that. Here is the code:

Rx.Observable
  .ajax({ url: 'https://jsonplaceholder.typicode.com/posts', method: 'GET', responseType: 'json' })
  .subscribe(function(data) { return data.response; });

I searched everywhere and there is no simple explanation.

Thanks!

Mark
  • 1,603
  • 3
  • 13
  • 18

3 Answers3

30

Observable.ajax can accept string or Object with the following interface:

interface AjaxRequest {
  url?: string; // URL of the request
  body?: any;  // The body of the request
  user?: string; 
  async?: boolean; // Whether the request is async
  method?: string; // Method of the request, such as GET, POST, PUT, PATCH, DELETE
  headers?: Object; // Optional headers
  timeout?: number;
  password?: string;
  hasContent?: boolean;
  crossDomain?: boolean; //true if a cross domain request, else false
  withCredentials?: boolean;
  createXHR?: () => XMLHttpRequest; //a function to override if you need to use an alternate XMLHttpRequest implementation
  progressSubscriber?: Subscriber<any>;
  responseType?: string;
}

see AjaxObservable.ts on GitHub

And here is examples:

const { Observable, combineLatest } = rxjs; // = require("rxjs")
const { ajax } = rxjs.ajax; // = require("rxjs/ajax")
const { map } = rxjs.operators; // = require("rxjs/operators")

// simple GET request example
const simple$ = ajax('https://httpbin.org/get');

// POST request example
const complex$ = ajax({
  url: 'https://httpbin.org/post',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-rxjs-is': 'Awesome!'
  },
  body: {
    hello: 'World!',
  }
});

const htmlSubscription = combineLatest(simple$, complex$)
  .subscribe(([simple, complex]) => {
    const simpleResponse = JSON.stringify(simple.response, null, 2);
    const complexResponse = JSON.stringify(complex.response, null, 2);
    document.getElementById('root').innerHTML = `
      <div>
        <span><b>GET</b> https://httpbin.org/get</span>
        <pre>${simpleResponse}</pre>

        <span><b>POST</b> https://httpbin.org/post</span>
        <pre>${complexResponse}</pre>
      </div>`;
  });
<script src="https://unpkg.com/rxjs@6.2.2/bundles/rxjs.umd.min.js"></script>
<div id="root">loading ...</div>
Oles Savluk
  • 4,315
  • 1
  • 26
  • 40
  • Yup I know you can map it or console.log it to view the response. Sorry I didn't explained my question well. Let's say you store that in a variable. Is there a way to call it and get the value back? – Mark Dec 22 '16 at 20:22
  • I've corrected my answer, now I'm using it "as a variable". If you wondering how to use Observables with your javascript code - take a look at examples in the documentation https://github.com/Reactive-Extensions/RxJS/tree/master/examples/autocomplete – Oles Savluk Dec 22 '16 at 23:14
  • Or take a look at this gist/course - https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 – Oles Savluk Dec 22 '16 at 23:15
  • 2
    Quick question does anyone know if RxJS can make Ajax calls then why does angular have its own http lib? – Ray Mar 02 '18 at 08:32
  • 1
    Ray Fan: because they're separate libraries. You can use RxJS without Angular. The reverse is not completely true as Angular uses Rx internally, but if you wanted to use the Rx AJAX capabilities instead of the Angular HTTP service, there's nothing stopping you from doing so... – TimTheEnchanter Jun 15 '18 at 19:37
6

Typescript version

"dependencies": { 
     "rxjs": "^5.1.0"
 }

and

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/dom/ajax';
import 'rxjs/add/observable/combineLatest';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/catch';


 const posts$ = Observable
  .ajax('https://jsonplaceholder.typicode.com/posts')
  .map(e => e.response);


  const htmlSubscription = posts$
  .subscribe(res => {
   console.log(JSON.stringify(res, null, 2));
  });
Aneer Geek
  • 2,795
  • 1
  • 16
  • 11
1

You want to use switchMap ..

const response$ = request$.switchMap((url) => {
  console.log(url);
  return fetch(url).then(res => res.json());
});

switchMap flattens a stream of streams and converts it to a stream that just emits the inner streams responses. If a second innerStream is emitted, the first stream is killed and the second one proceeds on its own.

See this bin which demos streamed requests over HTTP .. https://jsbin.com/duvetu/32/edit?html,js,console,output

danday74
  • 52,471
  • 49
  • 232
  • 283