当前位置: 动力学知识库 > 问答 > 编程问答 >

cyclejs - 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.

  • My demo application calls the NASA near earth objects API for the past 7 days and tries to display them.
  • There is a 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;

};

网友答案:

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)
    ]))
),
分享给朋友:
您可能感兴趣的文章:
随机阅读: