Tanmay
Tanmay

Reputation: 351

Handling JSON Objects in RxJS

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.

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

Answers (1)

int3h
int3h

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

Related Questions