Обработка объектов JSON в RxJS

Я новичок в циклах и rxjs в целом и надеялся, что кто-нибудь поможет мне решить мою проблему. Я пытаюсь создать демонстрационное приложение для своего понимания и зациклился на рендеринге объектов JSON в DOM.

  • Мое демонстрационное приложение вызывает API околоземных объектов НАСА за последние 7 дней и пытается их отобразить.
  • Внизу есть кнопка Load More, при нажатии на которую загружаются данные за предыдущие 7 дней (от Today - 7 до Today - 14).
  • Ответ, который я получаю от API, выглядит следующим образом

    { "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: [{...}], ... } }

Меня интересует объект JSON Near_earth_objects, но я не могу сопоставить его, потому что он является объектом. Как мне справиться с такими ситуациями? Ниже приведен код, который у меня есть

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;
};

person Tanmay    schedule 01.09.2016    source источник


Ответы (1)


Концептуально вы хотите извлечь записи nasa.near_earth_objects (т. е. превратить объект в массив), а затем преобразовать этот массив в наблюдаемую последовательность.

Я предполагаю, что вы уже используете lodash в своем проекте (вы можете сделать это без lodash, но вам просто нужно чтобы написать больше связующего кода вручную). Я также предполагаю, что вы импортируете Observable RxJS как Rx.Observable; измените имена ниже, чтобы они соответствовали вашему коду.

Вы можете выполнить первую задачу, используя _.toPairs(nasa.near_earth_objects), а вторую часть, вызвав .flatMap() и вернув Rx.Observable.from(near_objects). Полученный Observable будет выдавать элементы для каждого ключа в nasa.near_earth_objects. Каждый элемент будет массивом, где item[0] будет ключом элемента (например, 2016-09-06), а item[1] будет значением элемента.

Используя эту идею, вы можете заменить раковину DOM чем-то вроде:

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)
    ]))
),
person int3h    schedule 01.09.2016
comment
Я сделал то же самое, но без flatMap, с той лишь разницей, что разобрался сам, немного потрудившись. Помогли мне разобраться в моих понятиях. Большое спасибо. - person Tanmay; 06.09.2016