Reputation: 21304
I'm new to Bacon.js and FRP concepts. I'm struggling with implementing very basic functionality. I have an array of saved values in some local storage:
['A', 'B', 'C']
I have an asynchronous function that reads these values from storage (returns Promise).
I have 'add'
event to add new item to array and 'remove'
event to remove item from array. Every array update should write down updated array into the local storage.
I ended up with this solution but it doesn't work as expected:
const items = Bacon
.fromPromise(storage.get('items'))
.mapError(() => [])
.merge(Bacon.fromEvent(events, 'add').map(l => [l]))
.merge(Bacon.fromEvent(events, 'remove').map(l => [l]))
.skipDuplicates()
.filter(l => l)
.toProperty();
items.onValue((items) => {
// everytime rewrites storage with new array (but without old values)
console.log(items);
storage.put('items', items);
});
return items;
So at the start behavior is:
['A', 'B', 'C']
'add'
event is fired with D
item, it is not added to existed array, item replaces previous array values: ['D']
How I can do it with Bacon? I was thinking of update
method but unfortunately initial value of it should be not a stream or some other async action.
Upvotes: 1
Views: 254
Reputation: 3405
Use Bacon.update
. You can use an empty array as the initial value and provide the async initial value from your storage as one of the input streams for Bacon.update
. So, try something like
const items = Bacon.update([],
Bacon.fromPromise(storage.get('items')), (_, items) => items,
Bacon.fromEvent(events, 'add'), (items, newItem) => items.concat(newItem),
Bacon.fromEvent(events, 'remove'), (items, removedItem) =>
items.filter((item) => item != removedItem)
)
Upvotes: 2