I have a (Django) API that implements HATEOAS, so typically foreign keyed objects come through as URLs to other API endpoints. The following is the result from http://localhost:8000/brew-monitor/api/fermentations/1/
and is a Fermentation object with associated Dataset objects:
{
"id": 1,
"name": "My Beer",
"datasets": [
"http://localhost:8000/brew-monitor/api/datasets/1/",
"http://localhost:8000/brew-monitor/api/datasets/2/"
]
}
I need to write a service that will GET the above object and then iterate through the datasets
URLs and GET those as well (I know, maybe it can be more efficient but I'm teaching myself about HATEOAS).
A Dataset object looks like:
{
"id": 1,
"unit": "DEGF",
"variable_measured": "T",
"fermentation": "http://localhost:8000/brew-monitor/api/fermentations/1/",
"logging_device": "http://localhost:8000/brew-monitor/api/devices/1/",
"controls": [],
"active": true,
"datapoints": [
"http://localhost:8000/brew-monitor/api/datapoints/1/",
"http://localhost:8000/brew-monitor/api/datapoints/2/",
"http://localhost:8000/brew-monitor/api/datapoints/3/"
]
}
So I want the final result from my service to look like:
{
"id": 1,
"name": "My Beer",
"datasets": [
{
"id": 1,
"unit": "DEGF",
"variable_measured": "T",
"fermentation": "http://localhost:8000/brew-monitor/api/fermentations/1/",
"logging_device": "http://localhost:8000/brew-monitor/api/devices/1/",
"controls": [],
"active": true,
"datapoints": [
"http://localhost:8000/brew-monitor/api/datapoints/1/",
"http://localhost:8000/brew-monitor/api/datapoints/2/",
"http://localhost:8000/brew-monitor/api/datapoints/3/"
]
},
{
"id": 2,
"unit": "UNITLESS",
"variable_measured": "SG",
"fermentation": "http://localhost:8000/brew-monitor/api/fermentations/1/",
"logging_device": "http://localhost:8000/brew-monitor/api/devices/1/",
"controls": [],
"active": true,
"datapoints": [
"http://localhost:8000/brew-monitor/api/datapoints/4/",
"http://localhost:8000/brew-monitor/api/datapoints/5/",
"http://localhost:8000/brew-monitor/api/datapoints/6/"
]
}
]
}
I just know RxJS can do this. How?
EDIT: I have a solution that uses nested subscriptions but I think it's common knowledge that you should avoid that. So no nested subscriptions please.
I'd do something like this
const source$ = of({
"id": 1,
"name": "My Beer",
"datasets": [
"http://localhost:8000/brew-monitor/api/datasets/1/",
"http://localhost:8000/brew-monitor/api/datasets/2/"
]
});
const data$ = source$.pipe(
switchMap(source => this.getDatasets(source))
);
data$.subscribe(x => console.log(x));
function getDatasets(source) {
return forkJoin(source.datasets.map(endpoint => fakeHttpRequest(endpoint))).pipe(
map(results => ({...source, datasets: results}))
);
}
function fakeHttpRequest(endpoint) {
return of({
test: '123'
});
}
RXJS is awesome.