Ответ HTTP Cycle.js печатается как неопределенный в DOM
Я пытаюсь распечатать результаты HTTP-запроса к DOM в Cycle.js. Прямо сейчас я просто пытаюсь перечислить результаты, но они в конечном итоге будут в выпадающем списке.
Я создаю поток...
const facilityRequest$ = xs.of({
url: 'http://...',
category: 'facility'
});
Затем выберите это...
const facilityResponse$ = sources.HTTP
.select('facility')
.flatten()
.map(res => res.body.data)
.startWith([]);
Но когда я пытаюсь добавить результаты в топ вроде:
const vdom$ = form$.map(form =>
div([
facilityResponse$.map(res => p(res.id)),
])
);
Отображается как undefined
в окне браузера.
Однако, если я добавлю слушателя и запишу ответ на консоль, он отобразит массив средств:
facilityResponse$.addListener({
next: (res) => {
console.log(res);
}
})
2 ответа
Да! Вы нашли правильный способ обработки вашего потока массивов.
// CORRECT :)
const facilityVDom$ = facilityResponse$.map(facilities => // <- this is an array
ul( // <- notice no brackets here, because you already have an array
facilities.map(f => li(f.id)) // <- ...and array map returns an array
)
);
Однако это не проблема со списками.
Потоковые потоки похожи на массивы с течением времени, и их полезно рассматривать как массивы, но они не являются массивами и не взаимозаменяемы с массивами. Используйте только потоки в контексте STREAM и используйте массивы только в контексте ARRAY - отсюда и проблема с вашей первой попыткой:
// WRONG :(
const vdom$ = form$.map(form =>
div([ // <-- the `div` function can take an ARRAY of VDOMs as parameter
facilityResponse$.map(res => p(res.id)), // <-- this is a STREAM, not a VDOM
])
);
Здесь у вас есть две ошибки: 1) вы использовали поток в контексте массива, и 2) вы обернули то, что, по вашему мнению, было взаимозаменяемо с массивом в массиве. Таким образом, параметр, который вы предоставили div
Функция была массивом с одним элементом, и этот элемент был потоком, а не объектом VDOM.
Массив, предоставленный div
(или аналогичная) функция должна содержать объекты VDOM (или функции, которые возвращают объекты VDOM). Такие как:
div( [ p('1'), p('2'), p('3') ] ) // OR
div( [1,2,3].map(ii => p(ii)) ) // OR
let arr = [1,2,3]
div( arr.map(ii => p(ii)) )
map
Метод STREAM принимает функцию, и эта функция переключает вас из контекста потока. Вы можете использовать потоки внутри этой функции, но они, как правило, бесполезны и никогда не взаимозаменяемы с массивами.
stream$.map( // <- stream
function (elem) { // <- leaving stream
// regular javascript here
// transform each element of the stream
// and return it to the stream
return elem
}
) // <- back to stream
Оказывается, что списки, как известно, трудно обрабатывать с помощью cycle.js. Для этого вы можете использовать библиотеку https://github.com/cyclejs/collection или отобразить элементы массива и объединить их в один элемент (это зависит от того, что вы хотите с ним сделать).
Я решил свой конкретный случай с:
const facilityVDom$ = facilityResponse$.map(facilities => ul(facilities.map(f => li(f.id))));
Вот некоторые соответствующие обсуждения: