Reputation: 351
I am new to cyclejs and rxjs in general and was hoping someone could help me solve my problem. I am trying to build a demo application for my understanding and stuck with rendering JSON objects on the DOM.
Load More
button at the bottom which on clicking will load data of the previous 7 days (Today - 7
upto Today - 14
).The response I get from the API is as follows
{
"links" : {
"next" : "https://api.nasa.gov/neo/rest/v1/feed?start_date=2016-09-06&end_date=2016-09-12&detailed=false&api_key=DEMO_KEY",
"prev" : "https://api.nasa.gov/neo/rest/v1/feed?start_date=2016-08-25&end_date=2016-08-31&detailed=false&api_key=DEMO_KEY",
"self" : "https://api.nasa.gov/neo/rest/v1/feed?start_date=2016-08-31&end_date=2016-09-06&detailed=false&api_key=DEMO_KEY"
},
"element_count" : 39,
"near_earth_objects" : {
"2016-09-06" : [{
some data
},
{
some data
}],
2016-08-31: [{...}],
...
}
}
I am interested in near_earth_objects JSON object but I am unable to map it beacause of it being an Object. How do I handle such a situations? Below is the code that I have
function main(sources) {
const api_key = "DEMO_KEY";
const clickEvent$ = sources.DOM.select('.load-more').events('click');
const request$ = clickEvent$.map(() => {
return {
url: "https://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-06&end_date=2016-09-13&api_key=" + api_key,
method: "GET"
}
}).startWith({
url: "https://api.nasa.gov/neo/rest/v1/feed?start_date=2016-08-31&end_date=2016-09-06&api_key=" + api_key,
method: "GET"
});
const response$$ = sources.HTTP.filter(x$ => x$.url.indexOf("https://api.nasa.gov/neo/rest/v1/feed") != -1).select(response$$);
const response$ = response$$.switch(); //flatten the stream
const nasa$ = response$.map(response => {
return response.body
});
const sinks = {
DOM: nasa$.map(nasa =>
([nasa.near_earth_objects]).map(objects => {
var vdom = [];
//I am not very happy with this part. Can this be improved?
for (var key in objects) {
if (objects.hasOwnProperty(key)) {
vdom.push(objects[key].map(obj => div([
h1(obj.name)
])))
}
}
//returning the vdom does not render on the browser. vdom is an array of arrays. How should i correct this?
console.log(vdom);
return vdom;
})
),
HTTP: request$
};
return sinks;
};
Upvotes: 0
Views: 260
Reputation: 461
Conceptually, you want to extract the entries of nasa.near_earth_objects
(i.e., turn the Object into an Array), then flat map that Array into an Observable sequence.
I'll assume you're already using lodash in your project (you can do it without lodash, but you'll just need to write more glue code manually). I'll also assume you're importing RxJS' Observable as
Rx.Observable
; adjust the names below to suite your code.
You can accomplish the first task using _.toPairs(nasa.near_earth_objects)
, and the second part by calling .flatMap()
, and returning Rx.Observable.from(near_objects)
. The resulting Observable will emit items for each key in nasa.near_earth_objects
. Each item will be an array, with item[0]
being the item's key (e.g., 2016-09-06
) and item[1]
being the item's value.
Using that idea, you can replace your DOM
sink with something like:
nasa$.map(nasa => _.toPairs(nasa.near_earth_objects))
.flatMap(near_objects => Rx.Observable.from(near_objects))
.map(near_object => div([
h1(near_object[1].name)
]))
),
Upvotes: 1