med*_*y56 0 hateoas rxjs angular2-services
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/"
]
}
Run Code Online (Sandbox Code Playgroud)
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/"
]
}
Run Code Online (Sandbox Code Playgroud)
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/"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
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.
我会做这样的事情
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'
});
}
Run Code Online (Sandbox Code Playgroud)
RXJS很棒。